具有auto的initializer_list包含多个表达式

时间:2018-07-04 06:08:12

标签: c++ language-lawyer c++17 auto

一个简单的问题,

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 个答案:

答案 0 :(得分:22)

auto type deduction的规则自C ++ 17起已更改。

  

(从C ++ 17开始)
  在直接列表初始化中(但不在复制列表初始化中),   当从大括号初始化列表中推导auto的含义时,   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开始,对于直接初始化(即x11x22),括号初始化器必须只包含一个元素(它们的类型就是该元素的类型),然后变得不正确-形成的代码。

有关更多信息,请参见N3922N3681