试图理解C ++ 14中的[expr.const]

时间:2015-12-12 13:02:45

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

在C ++ 14标准中,它是否禁止下面的对象.attr("transform", function(d) {return "translate(" + width /2 + "," + height/d + ")"}); 声明

a

请参阅live example

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

2 个答案:

答案 0 :(得分: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{};
}

现在错误消息变为

error: call to non-constexpr function ‘A::A()’
     constexpr A a{};

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

  
      
  • 调用除constexpr构造函数以外的函数,用于文字类,constexpr函数或隐式调用简单析构函数(12.4)[...]
  •   
您已在问题中提及的

答案 1 :(得分:1)

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