试图理解C++14中的[expr.const]
Trying to understand [expr.const] in C++14
在C++14标准中,它是否禁止以下对象a
的声明?
class A{ int i = 1; public: A():i{1}{} };
int main()
{
constexpr A a{};
}
参见的实例
请注意,我强调了单词声明,因为我不认为§5.19[expr.const]p2中的要点(2.7.2)或(2.7.3)是这个问题的答案。
[dcl.constexpr]p9:
对象声明中使用的
constexpr
说明符将对象声明为const
。此类对象应具有文字类型并应进行初始化。如果它是由构造函数调用初始化的,该调用应为常量表达式(5.19)。[…]
您现在遇到的错误是因为您的类型不是文字类型。您的类型不是文字类型,因为它有自定义构造函数,但没有任何constexpr
构造函数。错误消息中的措辞对确切的要求相当清楚。
如果添加constexpr
构造函数(但不是默认构造函数),则错误消息将更改:
class A{ int i = 1; public: A():i{1}{} constexpr A(int){} };
int main()
{
constexpr A a{};
}
现在错误信息变为
错误:调用非常量表达式"A::A()"constexpr A A{};
这是我加粗的第二部分:它不是必须是常量表达式的初始化程序。你是对的,你的初始化程序根本不是一个表达式。构造函数调用必须是一个常量表达式,尽管它在源代码中没有显式表达,但它仍然是一个表达式。这一点在[expr.const]中有明确的说明:
- 对文字类的
constexpr
构造函数以外的函数的调用、constexpr
函数的调用,或对平凡析构函数(12.4)的隐式调用[…]
你在问题中已经提到了这一点。
好吧,您的默认构造函数不是constexpr
。因此,不能创建默认构造的constexpr
对象。