Я недавно наткнулся на этот код:
struct Foo{};
int main()
{
Foo a;
// clang++ deduces std::initializer_list
// g++5.1 deduces Foo
auto b{a};
a = b;
}
Он прекрасно компилируется с g ++ 5.1, но не работает в clang ++ (используется оба -std=c++11
а также -std=c++14
, те же результаты). Причина в том, что Clang ++ выводит тип b
как std::initializer_list<Foo>
, в то время как g++5.1
выводит как Foo
. AFAIK, тип действительно должен быть (действительно нелогичным) std::initializer_list
Вот. Почему g ++ 5 выводит тип как Foo
?
Существует предложение для C ++ 1z, которое реализует новые правила вывода типов для фигурной инициализации (N3922), и я думаю, что gcc реализовал их:
Для прямой инициализации списка:
1. Для фигурного списка инициализации, содержащего только один элемент, автоматическое удержание будет выводиться из этой записи;
2. Для braced-init-list с более чем одним элементом автоматическое удержание будет некорректным.[Пример:
auto x1 = { 1, 2 }; // decltype(x1) is std::initializer_list<int> auto x2 = { 1, 2.0 }; // error: cannot deduce element type auto x3{ 1, 2 }; // error: not a single element auto x4 = { 3 }; // decltype(x4) is std::initializer_list<int> auto x5{ 3 }; // decltype(x5) is int.
— конец примера]
Здесь патч gcc относительно новых изменений относительно «инициализации Единорога».