为什么{1,2}没有类型,但是decltype(a)格式正确?

时间:2014-11-29 06:10:54

标签: c++ initializer-list

标准说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(){ }

DEMO

此外decltype(a)std::initializer_list<int>。对我来说,它与初始化列表没有类型相矛盾。怎么了?

2 个答案:

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