将 'std::initializer_list<int>' 转换为 'int'

convert 'std::initializer_list<int>' to 'int'

为什么我不能将使用 "initializer_list" 分配的变量用作 "normal" 变量?

代码:

void stovr(int a){}
int main() {

   auto v {5}; // v is std::initializer_list<int>
   stovr(v);  // cannot convert 'std::initializer_list<int>' to 'int'

}

std::initializer_list<T> 无法转换为 T 的原因与 T[] 无法转换为 T 以及 vector<T> 无法转换为 [=11= 的原因相同]:如果你只知道你有一个std::initializer_list<T>,你不知道它有多少个元素

std::initializer_list<int> x = { 1, 2, 3 }; 完全有效。如果存在从 std::initializer_list<int>int 的隐式转换,您希望看到哪些值?

"A braced initializer has no type! A braced initializer has no type! A braced initializer has no type! No type corresponds to braced initializer"

(C) 斯科特迈耶斯。

这就是为什么在 C++11 和 C++14 中自动推导带有一个元素的大括号初始化器无法遵循直观规则的原因。

许多程序员认为这是标准中的缺陷。这就是提案 N3922: New Rules for auto deduction from braced-init-list 存在的原因。特别是:

For direct list-initialization:

  • For a braced-init-list with only a single element, auto deduction will deduce from that entry;
  • For a braced-init-list with more than one element, auto deduction will be ill-formed.

不确定这是否是重大更改,并且在此之后所有 C++14 代码都可以工作。

资料来源:Scott Meyers 在 CppCon 上就 C++11/C++14/C++17 中类型推导的怪癖进行了很好的讨论:link, including brace-initializer auto type deduction (starting from 29:00). Same thing in more details in his new book(并且有一个免费的采样器也包括那一章)