【问题标题】:Trying to understand [expr.const] in C++14试图理解 C++14 中的 [expr.const]
【发布时间】:2015-12-12 13:02:44
【问题描述】:

在C++14标准中,是否禁止声明下面的对象a

class A{ int i = 1; public: A():i{1}{} };

int main()
{
    constexpr A a{};
}

live example

请注意,我突出显示了 declaration 这个词,因为我认为 §5.19[expr.const]p2 中的要点 (2.7.2) 或 (2.7.3) 不是答案对于这个问题。

【问题讨论】:

    标签: c++ language-lawyer c++14 constexpr


    【解决方案1】:

    [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{};
    }
    

    现在错误信息变成了

    错误:调用非 constexpr 函数‘A::A()’ constexpr A a{};

    这是我加粗的第二部分:它不是必须是常量表达式的初始化程序。你是对的,你的初始化程序根本不是一个表达式。构造函数调用必须是一个常量表达式,尽管它没有在源代码中明确表示,但它仍然是一个表达式。这在 [expr.const] 中有相当清楚的说明:

    • 为文字类、constexpr 函数调用除 constexpr 构造函数之外的函数,或对普通析构函数 (12.4) 的隐式调用 [...]

    您已在问题中提及。

    【讨论】:

      【解决方案2】:

      好吧,你的默认构造函数不是constexpr。因此,您不能创建默认构造的constexpr 对象。

      【讨论】:

      • 但是标准中的什么地方是这样说的?请记住,声明 constexpr A{}; 中没有 表达式
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-11
      • 2016-10-15
      • 2013-10-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多