Почему g++5 выводит объект вместо initializer_list при автоматическом выводе типа

Я недавно наткнулся на этот код:

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?

1 ответ

Решение

Существует предложение для C++1z, которое реализует новые правила вывода типов для фигурной инициализации ( N3922), и я думаю, что gcc реализовал их:

Для прямой инициализации списка:
1. Для braced-init-list только с одним элементом автоматическое удержание будет выводиться из этой записи;
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, касающийся новых изменений в отношении "инициализации Unicorn".

Другие вопросы по тегам