17

据我了解(至少对于c++14),如果析构函数constexpr不是微不足道的(隐式生成的 or =default),它就不可能是。constexpr为具有非平凡析构函数的结构声明构造函数有什么意义?

struct X {
  int a_;

  constexpr X(int a) : a_{a} {}

  // constexpr ~X(){}; // Error dtor cannot be marked constexpr
  // ~X(){}; // causes  error at y declaration: temporary of non-literal type ‘X’
             // in a constant expression .
};

template <int N> struct Y {};

int main() {
  Y<X{3}.a_> y; // OK only if the destructor is trivial
  (void)y;
}
// tested with c++14 g++-5.1.0 and clang++ 3.5.0

例如std::unique_ptr有一些构造函数 constexpr(默认和nullptr_t),即使析构函数显然是显式定义的(如果对象是,确保它没有效果nullptr,但这并不意味着它仍然有一个显式定义的析构函数来检查对象处于空状态,正如我所见,即使是空析构函数也不允许在编译常量表达式中使用对象)

另一个例子是std::variant的提议:它几乎拥有所有的构造函数,constexpr尽管析构函数有签名~variant()并且它必须call get<T_j> *this).T_j::~T_j() with j being index().

我错过了什么?

4

1 回答 1

16

constexpr构造函数可用于常量初始化,作为静态初始化的一种形式,它保证在任何动态初始化发生之前发生。

例如,给定一个全局std::mutex

std::mutex mutex;

在符合标准的实现中(阅读:不是 MSVC),其他对象的构造函数可以安全地 lock 和 unlock mutex,因为std::mutex的构造函数是constexpr.

于 2015-06-10T20:15:51.667 回答