【问题标题】:Why must <initializer_list> be included for using auto?为什么必须包含 <initializer_list> 才能使用 auto?
【发布时间】:2013-06-14 09:57:01
【问题描述】:

在 SO 上已经有一个类似的 question,但我想强调 braced-init-lists 的另一个方面。考虑以下几点:

auto x = {1}; //(1)

除非包含标题 &lt;initializer_list&gt;,否则这是格式错误的 (8.5.4/2)。但为什么?标准说,模板std::initializer_list 没有预定义。这是否意味着声明 (1) 引入了一种新类型?在所有其他情况下,可以使用auto,例如

auto y = expr;

其中expr 是一个表达式,自动推导的类型已经存在。另一方面,从逻辑的角度来看,编译器必须为构造{1} 分配一个隐式类型,而std::initializer_list 则是另一个名称。但在声明 (1) 中,我们不想命名这种类型。那么为什么必须包含此标头。 nullptr 也有类似的情况。它的类型隐含存在,但要明确命名,您必须包含&lt;cstddef&gt;

【问题讨论】:

  • auto x = {expr}; 将根据语言规则将 x 推断为 std::initializer_list 类型 - 所以需要 #include &lt;initializer_list&gt;

标签: c++ c++11 types auto initializer-list


【解决方案1】:

那不一样。 std::nullptr_tstd::initializer_list 的规则实际上是不同的。

std::nullptr_t 只是一个内置类型的 typedef。它的定义是

namespace std {
  using nullptr_t = decltype(nullptr);
}

无论是否包含标题,类型都存在。

std::initializer_list 是类模板,而不是预定义类型。除非您包含定义它的标头,否则它实际上不存在。特别是,初始化列表{ 1 } 没有std::initializer_list&lt;int&gt; 类型;它根本没有类型,因为它不是表达式。 (初始化列表是特殊的句法结构,不能出现在表达式可以出现的任何地方。)

std::initializer_list 有点特别。一方面,对于如何从初始化列表语法初始化std::initializer_list 有一些特殊规则(分配一个数组并让对象引用它)。但是,这需要首先定义std::initializer_list

第二种特殊情况是auto类型推导。这里也有一个特殊的规则。但同样,这并不意味着编译器会自动定义类型;它只是意味着它会识别它。

【讨论】:

  • 如果我们想要形式化 自动类型推导(类型推断),那么构造 {1} 必须以某种方式具有类型。
  • @MWid 正如 Sebastian 所说,auto 说明符的类型推导有一个特殊规则,请参阅 [dcl.spec.auto]/6。 braced-init-list 是声明符的一部分,而不是表达式本身。
  • @DyP 我知道这就是麻烦的开始。例如,您可以使用 braced-init-list 作为赋值的右操作数。现在语言规则要求评估这个操作数。但是评估只为表达式定义。我想说的是,如果构造 {1} 在某种程度上没有类型甚至更好,我们会遇到问题。
  • @MWid 我不知道你在读什么标准。 C++11 允许将花括号初始化列表作为函数参数。调用括号的内容是expression-list,是initializer-list的别名,是initializer-clause的列表,可以是 assignment-expressionbraced-init-list。而带括号的表达式是 primary-expression,它是 assignment-expression 的一种可能形式,因此 5.18/2 示例也完全有效。
  • @MWid [expr.ass] 明确定义了区分大小写的评估,并将复杂的案例转发到函数调用语义。 (尽管参见 DR1527。)函数调用语义只是声明参数应使用适当的参数进行初始化,对于初始化列表,这是对 [dcl.init.list] 的隐式引用。特别是,p4 指定按顺序评估各个初始值设定项。
猜你喜欢
  • 2021-11-13
  • 1970-01-01
  • 1970-01-01
  • 2020-07-06
  • 1970-01-01
  • 1970-01-01
  • 2017-12-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多