C++ 如何解析:使用带括号的init list构造未命名的临时文件

C++ 如何解析:使用带括号的init list构造未命名的临时文件,c++,c++11,C++,C++11,我最近用了这个符号 ( const int[10] ){ 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 } 我记得它在C和C++中都是允许的,但是通过不同的语言机制。 < P>我相信C++中的形式化视图是一个未命名的临时结构,它是通过EXXLIIT类型转换(t)< /Case> CAST表达式,它将减少到 STATICECAST CAST ,它通过C++ 11节5.2.9/4:< /P>构造一个对象。 “表达式e可以使用static\u cast(e)形式的static\u ca

我最近用了这个符号

( const int[10] ){ 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 }
<>我记得它在C和C++中都是允许的,但是通过不同的语言机制。

< P>我相信C++中的形式化视图是一个未命名的临时结构,它是通过EXXLIIT类型转换<代码>(t)< /Case> CAST表达式,它将减少到<代码> STATICECAST CAST <代码>,它通过C++ 11节5.2.9/4:< /P>构造一个对象。 表达式
e
可以使用
static\u cast(e)
形式的
static\u cast(e)
显式转换为类型
T
t(8.5),code>格式良好

然而,C++11§5.4/2将强制转换表达式语法定义为一元表达式或递归的
type id
强制转换表达式,其中单个基本情况是简化为一元表达式

就我所知,带括号的init列表不是一个表达式

另一种观点是,它是通过函数表示法进行的显式类型转换,C++11§5.2.3/3

简单类型说明符或类型名说明符后跟大括号的init列表将创建临时 指定类型的对象

但据我所知,一个简单的类型说明符不能包含括号,而typename说明符包含C99中的关键字
typename

(实际上是先前的草案N1256)6.5.2.5/4:

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

一些编译器-在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]

可以通过标准符号实现标准C++中与显式类型转换相同的结果,但是必须定义数组类型的别名,因为函数表示需要一个简单类型指定符:

或:

模板
使用foo=T;
foo{10,9,8,7,6,5,4,3,2,1};
根据C99(实际上是先前的草案N1256)6.5.2.5/4:

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

一些编译器-在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]

可以通过标准符号实现标准C++中与显式类型转换相同的结果,但是必须定义数组类型的别名,因为函数表示需要一个简单类型指定符:

或:

模板
使用foo=T;
foo{10,9,8,7,6,5,4,3,2,1};

< /代码>这不是合法的C++。以下是正确的方法:
Alias{…}
@Xeo
Alias
应该做什么?
template使用Alias=T
,一个简单的别名,用于使代码可解析。我认为使用名称
identity
是一种传统做法。@Xeo:谢谢,显然你是对的(关于它无效)。C++代码在VisualC++ 12和G+4.4.2编译时失败,当指定了代码> -PoaNodie</C>时。没有<代码> -Poognic < /Calp> G++接受代码,大概是作为C++扩展的C99复合文字。这不是合法的C++。以下是正确的方法:
Alias{…}
@Xeo
Alias
应该做什么?
template使用Alias=T
,一个简单的别名,用于使代码可解析。我认为使用名称
identity
是一种传统做法。@Xeo:谢谢,显然你是对的(关于它无效)。C++代码在VisualC++ 12和G+4.4.2编译时失败,当指定了代码> -PoaNodie</C>时。没有<代码> -Poognic < /Calp> G++接受代码,大概是作为C++扩展的C99复合文字。+ 1谢谢这个C视图。事实证明,当指定了代码> >学究> <代码>时,C++代码无法用VisualC++和G+4.4.2编译。没有<代码> -Poognic < /Calp> G++接受代码,大概是作为C++扩展的C99复合文字。为什么Ro值?它不是临时的,可以用C写地址。事实上,同一段的p5说,
在这两种情况下,结果都是左值。
@Cubbi你当然是对的,我希望
decltype((const int[10]){10,9,8,7,6,5,4,3,2,1})
const int(&[10]
来表示左值,而实际上它只是
const int[10]
就像任何其他类型的文字一样。+1感谢您提供此C视图。事实证明,当指定了代码> >学究> <代码>时,C++代码无法用VisualC++和G+4.4.2编译。没有<代码> -Poognic < /Calp> G++接受代码,大概是作为C++扩展的C99复合文字。为什么Ro值?它不是临时的,可以用C写地址。事实上,同一段的p5 sa
template <typename T>
using foo = T;
foo<const int[10]>{ 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };