initializer_list с авто содержит несколько выражений
Довольно простой вопрос,
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};
Из книги Stroustroup C++, стр.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
Правило вывода автоматического типа изменилось с С++ 17.
(поскольку С++ 17)
При инициализации с прямым списком (но не в инициализации списка копий) при выводе значения auto из списка с привязкой к init-init-list-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>)
Поэтому перед С++ 17 все переменные в вашем примере работают нормально и имеют тип std::initializer_list<int>
. Но так как С++ 17 для прямой инициализации (т. x11
Для x11
и x22
), бит-инициализатор должен содержать только один элемент (и их тип будет типом элемента), а затем станет плохо сформированным кодом.
Подробнее см. N3922 и N3681.