以下代码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;
)添加到Foo
类doesn't change anything。
答案 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
与提供空体的构造函数之间的重要区别。)