gpt4 book ai didi

c++ - 为什么 auto x{3} 会推导出一个 initializer_list?

转载 作者:IT老高 更新时间:2023-10-28 13:23:50 24 4
gpt4 key购买 nike

我喜欢 C++11 中的 auto。太棒了。但是它有一个不一致的地方真的让我很紧张,因为我总是绊倒它:

int i = 3;       // i is an int with value 3
int i = int{3}; // i is an int with value 3
int i(3); // i is an int with value 3 (possibly narrowing, not in this case)
int i{3}; // i is an int with value 3

auto i = 3; // i is an int with value 3
auto i = int{3}; // i is an int with value 3
auto i(3); // i is an int with value 3
auto i{3}; // wtf, i is a std::initializer_list<int>?!

这种奇怪的行为会让新手感到困惑,也让有经验的用户感到恼火——C++ 有足够少的不一致和极端情况,人们必须牢记这一点。谁能解释一下为什么标准委员会决定在这种情况下引入一个新标准?

如果声明 std::initializer_list 类型的变量是有用的或经常做的事情,我可以理解,但根据我的经验,它几乎从不刻意——而且在极少数情况下,你确实想做,任何一个

std::initializer_list<int> l{3};
auto l = std::initializer_list<int>{3};
auto l = {3}; // No need to specify the type

会工作得很好。那么 auto x{i} 的特殊情况背后的原因是什么?

最佳答案

长话短说:

  • 花括号初始化表达式 {} 本身没有类型
  • auto 必须推断类型信息
  • int{3} 显然意味着“创建一个 int var,其值取自初始化列表”,因此它的类型只是 int 和可以在任何更广泛的上下文中使用(int i = int{3} 将起作用并且 auto i = int{3} 可以推断类型,因为右侧显然是类型int)
  • {3} 本身没有类型(它不能int,因为它不是 而是一个 initializer list),所以 auto 不起作用——但是,因为委员会认为 auto 在这种情况下仍然应该起作用,他们认为(是的,根据定义为无类型)初始化列表的“最佳”类型将是... std::initializer_list,您可能已经猜到了。

但是,正如您所指出的,这使得 auto 的整个行为在语义上非常不一致。这就是为什么向委员会提交了修改它的提案——即N3681N3912N3922。由于委员会没有就此事达成共识,以前的提案被拒绝为 FI3,http://isocpp.org/files/papers/n3852.html#FI3 , 当前 (N3922) 得到 adopted ca. Q1 of 2015 ;

tl;dr 你可以假设 standards-compliant compilers1bleeding-edge C++ support2要么已经有了新的、更理智的语义,要么很快就会有。

The Standardization Committee acknowledged the problem by adopting N3922 into draft C++17.

——原来如此

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

现在,无论好坏。

延伸阅读:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3681.html

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3912.html

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3922.html

http://scottmeyers.blogspot.com/2014/03/if-braced-initializers-have-no-type-why.html

http://herbsutter.com/2014/11/24/updates-to-my-trip-report/


1GCC 5.1(及以上)apparently uses N3922 even in C++11/C++14 mode

2Clang 3.8,带有警告

This is a backwards-incompatible change that is applied to all language versions that allow type deduction from auto (per the request of the C++ committee).

关于c++ - 为什么 auto x{3} 会推导出一个 initializer_list?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25612262/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com