В GCC7 реализован последний стандарт С++17 (будет принят в этом году). Хотелось бы обратить внимание, что изменились правила вывода типа auto при фигурной инициализации.
С++11, С++14 — при выводе типа использовали следующие правила:
Разница между обычной и фигурной инициализизацией была неинтуитивной и странной. Также это выглядело неинтуитивно при инициализируюшем захвате.
Скотт Майерс обращает внимание на это в своей книге.
Вывод типа возвращаемого значения, частично решал эту проблему.
Но ситуация проявляется вновь, в случае отдельной переменной auto
В С++17 для фигурной инициализации правила отныне такие:
1. При фигурной инициализации только с одним элементом, тип будет выведен из типа этого элемента.
2. При фигурной инициализации с несколькими элементами, вывод будет невозможным.
3. При фигурной инициализации с одним или несколькими элементами и присваиванием тип будет выведен как std::initializer_list
→ Предложение
→ Standard draft — 7.1.7.4.1 Placeholder type deduction
P.S. В комментариях выяснили, что попавшее в стандарт изменение, немного отличается от изначального предложения. Поправил статью.
С++11, С++14 — при выводе типа использовали следующие правила:
int foo(){ return 1; } auto x = foo(); // x = int auto x{foo()}; // x = initializer_list<int>
Разница между обычной и фигурной инициализизацией была неинтуитивной и странной. Также это выглядело неинтуитивно при инициализируюшем захвате.
Скотт Майерс обращает внимание на это в своей книге.
[x = foo()](){} // x = int [x{foo()}](){} // x = initializer_list<int>
Вывод типа возвращаемого значения, частично решал эту проблему.
auto f() { return {1,2}; // ошибка вывода типа, {1,2} не является корректным выражением }
Но ситуация проявляется вновь, в случае отдельной переменной auto
auto f() { auto x{1,2}; // x = initializer_list<int> return x; // возвращается как initializer_list, при попытке доступа возникает неопределённое поведение }
В С++17 для фигурной инициализации правила отныне такие:
1. При фигурной инициализации только с одним элементом, тип будет выведен из типа этого элемента.
auto x { 1 }; // x = int
2. При фигурной инициализации с несколькими элементами, вывод будет невозможным.
auto x1 { 1, 2 }; // ошибка: невозможно наличие нескольких элементов при фигурной инициализации auto
3. При фигурной инициализации с одним или несколькими элементами и присваиванием тип будет выведен как std::initializer_list
auto x = { 1, 2 }; // x = std::initializer_list<int>
→ Предложение
→ Standard draft — 7.1.7.4.1 Placeholder type deduction
P.S. В комментариях выяснили, что попавшее в стандарт изменение, немного отличается от изначального предложения. Поправил статью.
