它是如何解析的:用带括号的init列表构造未命名的临时对象
How is it parsed: constructing unnamed temporary with braced init list
我最近又遇到了符号
( const int[10] ){ 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 }
我记得它在C和c++中都是允许的,但是通过完全不同的语言机制。
我认为,在c++中,正式的观点是,它是通过显式类型转换(T)
强制转换表达式构造一个未命名的临时对象,它将简化为static_cast
,通过c++ 11§5.2.9/4:
”如果声明
T t(e);
格式良好,则表达式e
可以使用static_cast
形式的static_cast<T>(e)
显式转换为T
类型,对于某些虚构的临时变量t
(8.5)
然而,类型转换表达式语法在c++ 11§5.4/2中定义为一元表达式,或者递归地定义为(
类型id )
类型转换表达式,其中单个基本情况被简化为一元表达式。
就我所知,带括号的 init-list不是表达式?
另一种观点是,它是通过函数表示法进行的显式类型转换,c++ 11§5.2.3/3
”一个简单类型说明符或类型名称说明符跟一个带括号的init-list创建一个临时类型指定类型
的对象。
但是据我所知,简单类型说明符不能涉及括号,而类型说明符涉及关键字typename
?
Per C99(实际上是N1256,这是先前的草案)6.5.2.5/4:
由带圆括号的类型名和用大括号括起来的初始化式列表组成的后缀表达式是复合字面值。它提供了一个未命名的对象,其值由初始化列表给出。
一些编译器——至少是c++和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]
。请看这个演示程序。
你可以在标准c++中通过函数表示法实现显式类型转换,但是你必须为数组类型定义一个类型别名,因为函数表示法需要一个简单类型说明符:
using foo = const int[10];
foo{ 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
或Xeo的通用别名模板:
template <typename T>
using foo = T;
foo<const int[10]>{ 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
- Pybind11:将元组列表从Python传递到C++
- 从链接列表c++中删除一个项目
- 如何(从固定列表中)选择一个数字序列,该序列将与目标数字相加
- C++如何通过用户输入删除列表元素
- 读取文件的最后一行并输入到链接列表时出错
- 复制列表初始化的隐式转换的等级是多少
- LNK2038、MSVS2017 MAGMA的原因列表
- 不能在初始值设定项列表中将非常量表达式从类型 'int' 缩小到'unsigned long long'
- 没有为自己的结构调用列表推回方法
- 为什么基于范围类型的大括号上循环init列表是非法的c++
- 私有变量的读取晚于成员init列表
- 为什么只有一个元素的支撑init列表的类型会切换到元素本身的类型
- 使用支撑的init列表在向量中插入新元素
- 为什么支持的init列表在函数调用和构造函数调用中表现不同
- 调用带有支撑init列表的显式构造函数:是否不明确
- 有没有一种方法可以调用init列表中的成员函数
- 当返回一个用带括号的init列表初始化的对象时,我保证有一对构造函数和析构函数调用吗?
- 它是如何解析的:用带括号的init列表构造未命名的临时对象
- 实验make_array,我可以使用大括号init列表作为参数
- 空的大括号init列表会发出关于缺少字段初始值设定项的警告