标准说braced-init-list
没有类型。所以我预计像auto a = {1, 2};
这样的东西是不正确的。但它根本不是真的。
#include <iostream>
#include <initializer_list>
using namespace std;
auto a = {1, 2};
std::initializer_list<int> init_list = {1, 3, 6, 7};
decltype(a) b = init_list;
int main(){ }
此外decltype(a)
是std::initializer_list<int>
。对我来说,它与初始化列表没有类型相矛盾。怎么了?
答案 0 :(得分:3)
decltype({1, 2})
是非法的,但a
的类型已被推断。从最近的草案到C ++ 11标准,N3337:
§7.1.6.4/ 6
根据确定 declarator-id 的类型 8.3,使用 declarator-id 的声明变量的类型是根据其初始化程序的类型使用规则确定的 模板参数推导。让
T
成为已经存在的类型 确定变量标识符d
。从P
获取T
用新发明的类型替换auto
的出现次数 模板参数U
或者,如果初始化程序是 braced-init-list (8.5.4),std::initializer_list<U>
。推断的类型 变量d
然后是使用规则确定的推导A
函数调用中的模板参数推导(14.8.2.1),其中P
是函数模板参数类型,d
的初始值设定项是 相应的论点。如果扣除失败,则声明为 病态的。 [示例:auto x1 = { 1, 2 }; // decltype(x1) is std::initializer_list<int> auto x2 = { 1, 2.0 }; // error: cannot deduce element type
- 结束示例]
在您的问题的上下文中, braced-init-list 被推断为std::initializer_list<int>
,随后,decltype(a)
产生相同的类型。
答案 1 :(得分:1)
来自c ++标准(7.1.6.4自动说明符)
7 ....如果占位符是自动类型说明符,则使用模板参数推导的规则确定推导的类型。如果 扣除是用于返回语句,初始化器是a braced-init-list(8.5.4),该程序格式不正确。否则,获得 来自T的P用新的替换auto的出现 发明了类型模板参数U或者,如果初始化器是a braced-init-list,带有std :: initializer_list 。为U推断一个值 使用函数调用中的模板参数推导规则 (14.8.2.1),其中P是函数模板参数类型和 初始化程序是相应的参数。如果扣除失败,那么 声明是不正确的。否则,推断出的类型 变量或返回类型是通过将推导出的U代入 P. [
Example:
auto x1 = { 1, 2 }; // decltype(x1) is std::initializer_list<int>