Почему этот код работает в Clang++, но не в g++? - программирование
Подтвердить что ты не робот

Почему этот код работает в Clang++, но не в g++?

Рассмотрим следующий код:

struct Foo
{
    int x, y;

    Foo() = default;
    Foo(const Foo&) = delete;
    Foo& operator=(const Foo&) = delete;
};

int main()
{
    Foo f1 {1, 2};
    Foo f2 = {1, 2};
}

Компиляция с помощью clang++ не дает ошибок:

$ clang++ --version
Apple LLVM version 4.2 (clang-425.0.28) (based on LLVM 3.2svn)
Target: x86_64-apple-darwin12.4.0
Thread model: posix
$ clang++ -std=c++11 -stdlib=libc++ -pedantic t.cpp -o out
...builds and runs fine...

Однако компиляция с g++ 4.8.1 через ideone дает ошибки:

prog.cpp: In function ‘int main()’:
prog.cpp:12:17: error: no matching function for call to ‘Foo::Foo(<brace-enclosed initializer list>)’
     Foo f1 {1, 2};
                 ^
prog.cpp:12:17: note: candidate is:
prog.cpp:5:5: note: Foo::Foo()
     Foo() = default;
     ^
prog.cpp:5:5: note:   candidate expects 0 arguments, 2 provided
prog.cpp:13:19: error: could not convert ‘{1, 2}’ from ‘<brace-enclosed initializer list>’ to ‘Foo’
     Foo f2 = {1, 2};
                   ^

Если я удалю Foo(const Foo&) = delete;, то он компилируется отлично в g++ 4.8.1.

Есть ли ошибка в моем коде, которую игнорирует один компилятор, а другой нет?

4b9b3361

Ответ 1

С++ 11 8.5.1 [dcl.init.aggr] p1 определяет агрегированные типы:

Агрегат - это массив или класс (раздел 9) без конструкторов, предоставляемых пользователем (12.1), без инициализаторов скобок или равных для нестатических элементов данных (9.2), без частных или защищенных нестатических (раздел 11), нет базовых классов (раздел 10) и нет виртуальных функций (10.3).

предоставлено пользователем в 8.4.2 [dcl.fct.def.default] p4:

... Специальная функция-член предоставляется пользователю, если она объявлена ​​пользователем и не явно по умолчанию или удалено в его первом объявлении.

Foo имеет два объявленных пользователем конструктора, оба из которых явно дефолтны или удалены в первом объявлении, поэтому Foo является агрегатом.

GCC неверен.

EDIT: Это ошибка GCC 52707.