2014-09-18 22 views
10

Perché static_assert deve essere al di fuori della definizione della classe?static_assert definizione classe interna/esterna

In mancanza di codice

#include <type_traits> 

class A 
{ 
public: 
    A(A&&) noexcept {} 
    static_assert(std::is_nothrow_move_constructible<A>::value, "ERROR"); 
}; 

int main() 
{ 
} 

codice di lavoro

#include <type_traits> 

class A 
{ 
public: 
    A(A&&) noexcept {} 

}; 

static_assert(std::is_nothrow_move_constructible<A>::value, "ERROR"); 

int main() 
{ 
} 

E quando è opportuno utilizzare static_asserts nella definizione di una classe o struct?

+0

Che cosa non funziona per il primo? C'è un messaggio di errore? – 0x499602D2

+0

Ho modificato il titolo della domanda per abbinare il contenuto della domanda. – aschepler

+0

@ 0x499602D2 Il codice in mancanza di dare questo messaggio quando si compila con g ++ --std = C++ 11 {code} is_nothrow_move_constructible.cpp: 8: 1: errore: asserzione static non riuscita: errore static_assert (std :: :: is_nothrow_move_constructible valore, "ERRORE"); {code} – Parkesy

risposta

17

Per quanto riguarda il posizionamento di static_assert in sé, entrambe le versioni del codice sono valide. Quindi, no, static_assert non deve essere al di fuori della definizione della classe. Formalmente static_assert è una dichiarazione . È consentito ovunque siano consentite le dichiarazioni.

Il problema riscontrato non ha nulla a che vedere con static_assert stesso.

Il problema qui è che l'espressione che si usa come argomento di tuo static_assert (std::is_nothrow_move_constructible) richiede il tipo di classe di essere completa per funzionare correttamente. Ma all'interno della definizione di classe A il tipo di classe A non è ancora completo, il che rende l'espressione di argomento non valida. Questo è il motivo per cui il tuo static_assert funziona come previsto solo al di fuori della definizione della classe, dove A è completo. Tuttavia, si tratta interamente dell'uso corretto di std::is_nothrow_move_constructible, non dello stesso static_assert.

Nota, che il tipo di classe degli oggetti della funzione membro interno è visto nella sua interezza, come tipo completo, anche se la funzione membro è definita all'interno della definizione di classe. Utilizzando questa funzione è possibile riscrivere il codice come

class A 
{ 
public: 
    A(A&&) noexcept { 
     static_assert(std::is_nothrow_move_constructible<A>::value, "ERROR"); 
    } 
}; 

e std::is_nothrow_move_constructible<A> produrrà il risultato corretto.

+0

E, AFAIK, 'static_assert' può * essere utilizzato all'interno del corpo di una funzione * –

Problemi correlati