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

Che*_*Alf 13 c++ c++11

我最近再次遇到了符号

( const int[10] ){ 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 }
Run Code Online (Sandbox Code Playgroud)

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

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

"表达e可以显式转换到类型T使用static_cast的形式的static_cast<T>(e),如果声明T t(e);是良好的形成,对于某些发明临时变量t(8.5)

但是,Cast-expression语法由C++11§5.4/ 2定义为一元表达式,或者递归地,一个( type-id 强制转换) 表达式,其中单个基本情况是简化为一元表达式.

据我所知,一个支撑的init-list不是表达式?

另一种观点可能是它是通过功能符号进行的显式类型转换,C++11§5.2.3/ 3,

"一个simple-type-specifiertypename-specifier后跟一个braced-init-list创建一个指定类型的临时对象

但据我所知,简单类型说明符不能涉及括号,而typename-specifier涉及关键字typename

Cas*_*sey 6

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

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

一些编译器 - 至少是g ++和clang - 在C++中提供C99复合文字作为扩展.语义上,表达式

( const int[10] ){ 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 }
Run Code Online (Sandbox Code Playgroud)

是一个类型的文字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].请参阅此演示程序.

您可以使用功能表示法通过显式类型转换在标准C++中实现相同的结果,但您必须为数组类型定义类型别名,因为功能表示法需要简单类型说明符:

using foo = const int[10];
foo{ 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
Run Code Online (Sandbox Code Playgroud)

或者Xeo的一般别名模板:

template <typename T>
using foo = T;
foo<const int[10]>{ 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
Run Code Online (Sandbox Code Playgroud)