我应该将编译器生成的构造函数标记为 constexpr 吗?

Should I mark a compiler-generated constructor as constexpr?

本文关键字:记为 constexpr 构造函数 编译器 我应该      更新时间:2023-10-16

做以下操作有区别吗:

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构造函数而不知不觉。