2015-06-10 11 views
17

Per quanto comprendo (almeno per c++14), un distruttore non può essere constexpr se non è banale (implicito generato o =default). Che senso ha dichiarare i costruttori constexpr per strutture con distruttori non banali?perché dichiarare costruttori constrexpr per classi con distruttori non banali (es 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 

Per esempio std::unique_ptr ha qualche constructorsconstexpr (default e nullptr_t), anche se il distruttore è ovviamente definita esplicitamente (certo non ha effetti se l'oggetto è nullptr, ma non vuol dire che ha ancora un distruttore esplicitamente definito per verificare se l'oggetto si trova in uno stato vuoto e, come ho visto, anche un distruttore vuoto non consente l'utilizzo di un oggetto in un'espressione costante della compilazione)

Altro esempio è la proposta per std::variant: ha quasi tutti i costruttori constexpr sebbene il distruttore ha la firma ~variant() e deve call get<T_j> *this).T_j::~T_j() with j being index().

Cosa mi manca?

+0

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

+0

Ti manca il fatto che C++ non ha più senso. –

+0

inb4 lol @ "altro" –

risposta

16

constexpr I costruttori possono essere utilizzati per l'inizializzazione costante, che, come forma di inizializzazione statica, è garantita prima che avvenga qualsiasi inizializzazione dinamica.

Per esempio, dato un globale std::mutex:

std::mutex mutex; 

In un'implementazione conforme (leggi: non MSVC), costruttori di altri oggetti possono tranquillamente bloccare e sbloccare mutex, perché il costruttore std::mutex s' è constexpr.

+0

Non è stato risolto da MS quello per VS2015? Inoltre, http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2976.html – dyp

+1

@dyp Non per 'std :: mutex'. –

+0

Ti capita di avere un link dove posso leggere di più a riguardo? MSDN dice che è un costruttore 'constexpr', quindi * l'inizializzazione costante * manca in VS2015 o è qualcosa di specifico per' std :: mutex'? – dyp

Problemi correlati