2015-06-10 15 views
17

Soweit ich (zumindest für c++14) zu verstehen, kann ein destructor nicht constexpr, wenn es nicht trivial (implizit erzeugt oder =default ist). Was ist der Zweck, constexpr Konstruktoren für Strukturen mit nicht-trivialen Destruktoren zu deklarieren?warum constrexpr Konstruktoren für Klassen mit nicht-trivialen Destruktoren deklarieren (zB unique_ptr, std :: Variante)

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 Beispiel std::unique_ptr hat einig constructorsconstexpr (Standard und nullptr_t), obwohl der destructor offensichtlich explizit (sicher definiert ist, hat es keine Auswirkungen, wenn das Objekt nullptr, aber bedeutet das nicht, dass es immer noch ein explizit definierter Destruktor, um zu prüfen, ob sich das Objekt in einem leeren Zustand befindet, und selbst ein leerer Destruktor erlaubt es nicht, ein Objekt in einem Kompilierungskonstantenausdruck zu verwenden.

Another Beispiel ist der Vorschlag für std::variant: Es hat fast alle Konstruktoren constexpr obwohl der Destruktor hat die Signatur ~variant() und es muss call get<T_j> *this).T_j::~T_j() with j being index().

Was fehlt mir?

+0

Siehe auch: http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2976.html – dyp

+0

Sie vermissen die Tatsache, dass C++ keinen blutigen Sinn mehr macht. –

+0

inb4 lol @ "mehr" –

Antwort

16

constexpr Konstruktoren können für die konstante Initialisierung verwendet werden, was als eine Art statische Initialisierung garantiert ist, bevor eine dynamische Initialisierung stattfindet.

Zum Beispiel gegeben globalen std::mutex:

std::mutex mutex; 

In einer konformen Implementierung (sprich: nicht MSVC), Konstrukteure anderer Objekte können sicher sperren und entsperren mutex, weil std::mutex ‚s Konstruktor constexpr ist.

+0

Hat MS das für VS2015 nicht behoben? Http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2976.html – dyp

+1

@dyp Nicht für 'std :: mutex'. –

+0

Würdest du zufällig einen Link haben, über den ich mehr darüber lesen kann? MSDN sagt, es ist ein "constexpr" -Konstruktor, also ist * konstante Initialisierung * in VS2015 fehlt oder ist es etwas spezifisch für 'std :: mutex'? – dyp

Verwandte Themen