initializer_list с auto содержит несколько выражений - PullRequest
0 голосов
/ 04 июля 2018

Достаточно простой вопрос,

auto x11 {1,2,3,4};
auto x1 = {1,2,3,4};
auto x22 {1.0, 2.25, 3.5};
auto x2 = {1.0, 2.25, 3.5};

Насколько я понимаю, здесь не должно быть различий в отношении наличия = или нет. Однако, используя llvm / clang 6.0.0 (с --std = c ++ 17), я получаю:

main1.cpp:35:17: error: initializer for variable 'x11' with type 'auto' contains multiple
  expressions
auto x11 {1,2,3,4};
~~~~~~~~    ^

main1.cpp:37:20: error: initializer for variable 'x22' with type 'auto' contains multiple
  expressions
auto x22 {1.0, 2.25, 3.5};

Из книги C ++ Stroustroup, стр. 162:

auto x1 {1,2,3,4}; // x1 is an initializer_list<int>
auto x2 {1.0, 2.25, 3.5 }; // x2 is an initializer_list of<double>

Итак, действительно ли проблема в том, что там нет = ?

1 Ответ

0 голосов
/ 04 июля 2018

Правило автоматического удержания типа изменено с C ++ 17.

(начиная с C ++ 17)
В прямой инициализации списка (но не в инициализации копирования списка), при выводе значения auto из списка фигурных скобок init Braced-init-list должен содержать только один элемент и тип auto будет тип этого элемента:

auto x1 = {3}; // x1 is std::initializer_list<int>
auto x2{1, 2}; // error: not a single element
auto x3{3};    // x3 is int
               // (before C++17 x2 and x3 were both std::initializer_list<int>)

Так что до C ++ 17 все переменные в вашем образце работают нормально и имеют тип std::initializer_list<int>. Но, начиная с C ++ 17, для прямой инициализации (то есть для x11 и x22) скобочный инициализатор должен содержать только один элемент (и их тип будет типом элемента), а затем становится плохо сформированным кодом.

Подробнее см. N3922 и N3681 .

...