我应该将编译器生成的构造函数标记为 constexpr 吗?
Should I mark a compiler-generated constructor as constexpr?
做以下操作有区别吗:
X() = default;
和
constexpr X() = default;
在常量表达式中默认构造类工作正常,那么这两个示例之间有区别吗?我应该使用一个而不是另一个吗?
由于隐式构造函数实际上在您的情况下是constexpr
的......
[C++11: 12.1/6]:
[..]如果该用户编写的默认构造函数满足constexpr
构造函数 (7.1.5) 的要求,则隐式定义的默认构造函数constexpr
。[..]
[C++11: 7.1.5/3]:
constexpr
函数的定义应满足以下约束:
- 它不应是虚拟的(10.3);
- 其返回类型应为文本类型;
- 其每个参数类型应为文本类型;
- 其功能主体应为
= delete
、= default
或仅包含的复合语句
- 空语句,
- static_assert声明
typedef
不定义类或枚举的声明和别名声明,- 使用声明,
- using-指令,
- 并且只有一个返回语句;
- 初始化返回值 (6.6.3, 8.5) 时使用的每个构造函数调用和隐式转换都应是常量表达式 (5.19) 中允许的调用和隐式转换之一。
声明实际上是等价的:
[C++11: 8.4.2/2]:
一个显式默认函数只有在被隐式声明为constexpr
时才可以声明constexpr
,并且只有当它与隐式声明上的异常规范兼容(15.4)时,才可以具有显式异常规范。如果函数在其第一个声明中显式默认,
- 隐式地认为是
constexpr
,如果隐式声明是,- 它被隐式地认为具有与隐式声明相同的异常规范(15.4),并且
对于复制构造函数、移动- 构造函数、复制赋值运算符或移动赋值运算符,它应具有与隐式声明相同的参数类型。
所以要么做 - 没关系。
在一般情况下,如果你肯定希望构造函数constexpr
,但是,保留关键字可能是明智的,这样如果它不符合条件,你至少会得到一个编译器错误;省略它,你可能会得到一个非constexpr
构造函数而不知不觉。
相关文章:
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 是否可以将带有字符串化运算符的宏转换为 constexpr?
- 将INT32BE宏转换为 constexpr 是否正确?
- 为什么 std::array 的运算符 ==() 没有标记为 constexpr?
- 将 'hana::string' 转换为 'constexpr const char (&)[]'
- 如果我的班级是字面的班级,那么将我的类的对象声明为constexpr是多余的
- 将结构转换为 constexpr 数组uint8_t
- 将默认赋值运算符声明为 constexpr:哪个编译器是正确的?
- 将variadic模板转换为constexpr
- 将set函数(setter)标记为constexpr的目的是什么
- 是否可以在 constexpr 函数中遍历枚举成员,因此值为 constexpr
- 显式默认函数不能声明为 constexpr,因为隐式声明不是 constexpr
- 将静态 const 成员重新声明为 constexpr 是否会自动使其符合内联条件
- 是否可以将类型别名定义为constexpr函数
- 如何将模板大小的数组初始化转换为 constexpr 初始化
- 我应该将编译器生成的构造函数标记为 constexpr 吗?
- 只要调用的函数是用constexpr指定的,就将委托方法声明为constexpr
- static_assert 无法将 const char* 模板参数识别为 constexpr:g++ 错误?
- 将代码转换为 constexpr
- 什么时候应该将构造函数设置为 constexpr