它是如何解析的:使用braced init list构造未命名的临时文件

时间:2014-06-24 11:26:32

标签: c++ c++11

我最近yet again encountered符号

( const int[10] ){ 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 }

我记得它在C和C ++中都是允许的,但是通过完全不同的语言机制。

我相信在C ++中,正式视图是通过epxlicit类型转换(T) cast-expression 构建一个未命名的临时文件,它将减少为static_cast ,通过C ++11§5.2.9/ 4构建一个对象:

  

如果声明{{e,则可以使用T格式static_caststatic_cast<T>(e)显式转换为T t(e);类型对于一些发明的临时变量t(8.5)

,1}}格式正确

但是, cast-expression 语法由C ++11§5.4/ 2定义为一元表达式或递归地为{{1} } type-id ( cast-expression ,其中单个基本案例是一元表达式

据我所知, braced init-list 不是表达式?

另一种观点可能是通过功能表示法进行显式类型转换,C ++11§5.2.3/ 3,

  

简单类型说明符 typename-specifier ,后跟 braced-init-list 创造一个临时的   指定类型的对象

但据我所知, simple-type-specifier 不能涉及括号,而 typename-specifier 涉及关键字)

1 个答案:

答案 0 :(得分:6)

每C99(嗯,实际上是N1256,这是先前的草案)6.5.2.5/4:

  

后缀表达式由带括号的类型名称后跟括号括起的初始值设定项列表组成,是一个复合文字。它提供了一个未命名的对象,其值由初始化列表给出。

一些编译器 - at least g++ and clang - 在C ++中提供C99复合文字作为扩展。语义上,表达式

( const int[10] ){ 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 }

const int[10]类型的文字:decltype((const int[10]){ 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 })实际上是const int[10]注意: g ++版本之间存在一些关于确切类型的不一致:4.9之前的g ++版本说decltype((const int[10]){ 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 })const int(&)[10]See this demonstration program

您可以通过功能表示法在标准C ++中使用显式类型转换获得相同的结果,但您必须为数组类型定义类型别名,因为功能表示法需要 simple-type-specifier :< / p>

using foo = const int[10];
foo{ 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };

Xeo's general alias template

template <typename T>
using foo = T;
foo<const int[10]>{ 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };