【发布时间】:2015-08-26 06:45:33
【问题描述】:
据我所知(至少对于c++14),如果析构函数不是微不足道的(隐式生成或=default),它就不能是constexpr。为具有非平凡析构函数的结构声明 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有一些constructorsconstexpr(默认和nullptr_t),即使析构函数显然是明确定义的(如果对象是nullptr,确保它没有影响,但没有这意味着它仍然有一个显式定义的析构函数来检查对象是否处于空状态,正如我所见,即使是空析构函数也不允许在编译常量表达式中使用对象)
另一个例子是std::variant 的提案:它几乎拥有所有的构造函数constexpr,尽管析构函数的签名是~variant() 并且它必须是call get<T_j> *this).T_j::~T_j() with j being index().
我错过了什么?
【问题讨论】:
-
您错过了一个事实,即 C++ 不再具有血腥意义。
-
inb4 大声笑@“更多”
-
@LightnessRacesinOrbit N3597 建议使用
constexpr析构函数,但“没有已知的令人信服的用例”。因此,可以在常量表达式中使用的类型需要有一个普通的 dtor。 OTOH,常量 init 是具有不能在常量表达式中使用的常量表达式的类型的用例。 -
@dyp:甚至没有必要考虑这些。 (请注意,我不一定说它应该或可以自动化)