编译器是否默认生成构造函数constexpr?

时间:2018-04-24 11:48:42

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

以下代码compiles successfully包含 clang ++ 3.8.0 g ++ 7.2.0 (编译标志为-std=c++14 -Wall -Wextra -Werror -pedantic-errors):

struct Foo
{
    constexpr operator bool() const
    {
        return false;
    }
};


int main()
{
    constexpr bool b = Foo{};

    (void)b;
}

编译器标准的这种行为是否合规?请注意,将任何成员(例如int i;)添加到Foodoesn't change anything

2 个答案:

答案 0 :(得分:3)

是的,隐式构造函数是constexpr这种情况。通常,它取决于子对象。

  

[class.ctor]

     

默认构造函数是默认构造函数,默认构造函数是默认构造函数,默认构造函数是默认使用的(6.2)   创建一个类类型(4.5)的对象,或者在第一次声明后显式默认的对象。该   隐式定义的默认构造函数执行将要执行的类的初始化集   通过用户编写的该类的默认构造函数,没有ctor-initializer(15.6.2)和一个空复合 -   声明。如果该用户编写的默认构造函数不正确,则程序格式错误。 如果那样   用户编写的默认构造函数将满足constexpr构造函数(10.1.5)的要求   隐式定义的默认构造函数是constexpr 。 ...... [snip]

constexpr构造函数的相关要求:

  

[dcl.constexpr]

     
      
  • 该课程不得有任何虚拟基类;
  •   
  • 对于非委托构造函数,选择每个构造函数来初始化非静态数据成员和   基类子对象应是constexpr构造函数;
  •   

答案 1 :(得分:1)

是的。编译器生成的默认构造函数和简单的构造函数

Foo() = default;

两者使您能够编写constexpr bool b = Foo{};,假设可以构造所有类成员constexpr。请注意,如果您已经写过

Foo(){}

然后constexpr被允许。 (default与提供空体的构造函数之间的重要区别。)