2016-03-29 22 views
5

voglio controllare la dimensione della seguente struttura sulla creazione di un'istanza con static_assert per vincolare che il senza nome struct è fitto, in tal modo la dimensione del A è equivalente a sizeof(T) * 3.statico affermare la dimensione di un tipo di modello su di un'istanza

template <typename T> 
struct A 
{ 
    union 
    { 
     struct { T a, b, c; }; 
     T arr[3]; 
    }; 
}; 

Questo potrebbe essere fatto con

static_assert(sizeof(A<T>) == sizeof(T) * 3, "hey something went wrong"); 

Tuttavia

  • dal A<T> è ancora un tipo incompleto all'interno della sua definizione di classe, mettendo sopra static_assert nella definizione di classe è non un'opzione

  • static_assert con sizeof non valuta all'interno delle funzioni non-istanziata in tutti i compilatori (come Clang), in modo da mettere in funzione un membro fittizio non è un'opzione

  • mettendo static_assert a un costruttore o distruttore sarebbe una soluzione , ma nell'esempio precedente esiste alcun costruttore definito dall'utente (pensare a aggregati), inoltre immaginare il caso di più costruttori, dove avrei evitare eseguendo l'affermazione in tutti

  • ereditare A da un altro struct ed eseguendo static_assert su quello nel de finition di A sarebbe una soluzione, ma voglio mantenere il semplice struct, senza fare confusione con le strutture di supporto

Qualsiasi altra soluzione che mi manca?

Ho deciso di ripristinare questa domanda e tenerla aperta per possibili soluzioni in futuro.

+0

Naturalmente 'sizeof' non è consentito su tipi incomlete ma quando si istanzia la struttura del tipo di' T' non può essere incompleto, altrimenti semplicemente non verrebbe compilato, con o senza 'sizeof' – SomeWittyUsername

+0

Non è possibile creare un sindacato senza conoscere le dimensioni dei tipi, quindi è necessario che il tipo sia completo comunque. Quindi, la prima soluzione dovrebbe andare bene. – OMGtechy

+1

C'è ancora il distruttore ma (come per il costruttore) si possono rompere alcune proprietà (aggregate, banalmente distruttibili). E devi abilitare lo spostamento/copia costruttore/assegnazione. – Jarod42

risposta

0

Una funzione membro speciale (quasi) garanzia di essere istanziato è il distruttore:

~A() noexcept { static_assert(sizeof(A<T>) == sizeof(T) * 3, "hey something went wrong"); } 
+0

Sì, ma come @ Jarod42 ha anche affermato nel suo commento, che interromperà la regola aggregata e banalmente la disabilitabilità predefinita. – plasmacel