作为this SO question讨论期间提出的一个问题:
声明constexpr std::initializer_list
对象是否合法,可能是N3471?例如:
constexpr std::initializer_list<int> my_list{};
为什么我认为它可能不合法:initializer_list
必须是字面类型;但有没有保证它是文字类型?
来自N3485的引文。
[dcl.constexpr] / 9:
对象声明中使用的constexpr说明符将对象声明为const。这样的对象应该有 文字类型,应初始化。
文字类型要求,[basic.types] / 10,子项目类类型:
- 具有以下所有属性的类类型(第9条):
- 它有一个简单的析构函数,
- 非静态数据成员(如果有)的brace-or-equal-initializers中的每个构造函数调用和完全表达式都是常量表达式(5.19),
- 它是一个聚合类型(8.5.1)或者至少有一个constexpr构造函数或构造函数模板,它不是复制或移动构造函数,并且
- 它的所有非静态数据成员和基类都是非易失性文字类型。
奖励积分;)如果
回答constexpr std::initializer_list<int> my_list = {1,2,3,4,5};
是合法的(带参考)。虽然我认为上述+ [dcl.init.list] / 5
涵盖了这一点答案 0 :(得分:8)
更新:在CWG DR 1684的解决方案取消了下面引用的要求后,情况变得更加复杂。可以在this discussion on the std-discussion mailing list和相关问题Why isn't `std::initializer_list` defined as a literal type?
中找到更多信息[decl.constexpr] / 8:
非静态成员函数的constexpr说明符不是构造函数,声明该成员函数为const(9.3.1)。 [...]该函数所属的类应为文字类型(3.9)。
因此,N3471保证std::initializer_list
的更改将是文字类型。
请注意,仅constexpr
ctor不需要std::initializer_list
为文字类型,请参阅[dcl.constexpr] / 4 + 8。附注:在常量初始化 [basic.start.init] / 2]期间,可以初始化具有constexpr
ctor的非文字类型的对象(静态初始化的一部分,在任何动态初始化之前执行。)