Насколько я понимаю (по крайней мере, для c++14
), деструктор не может быть constexpr
, если он не является тривиальным (неявным сгенерированным или =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().
Что мне не хватает?