why constrexpr-Konstruktoren für Klassen mit nicht-trivialen Destruktoren deklarieren (z. B. unique_ptr, std :: variant)
Soweit ich verstehe (zumindest fürc++14
), ein Destruktor kann nicht @ seconstexpr
wenn es nicht trivial ist (implizit generiert oder=default
). Was ist der Sinn der Deklaration vonconstexpr
Konstruktoren für Strukturen mit nicht-trivialen Destruktoren?
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
Zum Beispielstd::unique_ptr
hat welche Konstrukteure constexpr
(Standard undnullptr_t
), obwohl der Destruktor offensichtlich explizit definiert ist (sicher, dass er keine Auswirkungen hat, wenn das Objekt @ inullptr
, aber heißt das nicht, dass es immer noch einen explizit definierten Destruktor hat, um zu überprüfen, ob das Objekt leer ist, und wie ich gesehen habe, erlaubt selbst ein leerer Destruktor nicht, dass ein Objekt verwendet wird in einem kompilierten konstanten Ausdruck)
Ein weiteres Beispiel ist der Vorschlag fürstd :: variant: Es hat fast alle Konstrukteureconstexpr
obwohl der Destruktor die Signatur hat~variant()
und es musscall get<T_j> *this).T_j::~T_j() with j being index().
Was vermisse ich