2011-01-28 11 views
15

Ciao,C'è un modo semplice per sapere se una classe/struct non ha membri di dati?

c'è un modo semplice in C++ per dire (in fase di compilazione) se una classe/struttura non ha membri di dati?

E.g. struct T{};

Il mio primo pensiero è stato quello di confrontare sizeof(T)==0, ma questo sembra sempre di essere almeno 1.

La risposta ovvia sarebbe quella di guardare solo il codice, ma vorrei passare su questo.

+4

qualificherebbe un v-table come membro dati? È una specie di nascosto. – CashCow

+0

'sizeof (T) == 0' sembra esistere in D, ma è vietato dallo standard C++, corretto. –

+0

Curioso perché vuoi farlo? –

risposta

13

È possibile derivare da questa classe in un'altra vuota e controllare se sizeof(OtherClass) == 1. Boost fa questo nel suo tratto di tipo is_empty.

testato:

template <typename T> 
struct is_empty { 
    struct helper_ : T { int x; }; 
    static bool const VALUE = sizeof(helper_) == sizeof(int); 
}; 

Tuttavia, questo si basa sull'ottimizzazione classe base vuota (ma tutti i compilatori moderni fare questo).

+2

Non funziona. Come dice CashCow, questo non funzionerà per le classi con funzioni virtuali. – UmmaGumma

+3

@Ashot: Questo non dovrebbe essere "non funzionerà" tanto quanto "non funzionerà con alcune definizioni di vuoto". – GManNickG

+0

@Ashot Martirosyan ... ma la soluzione può essere modificata derivando da alcune classi di helper di base con funzioni virtuali fittizie come pure dalla classe in fase di test – user396672

11

Se il compilatore supporta questo aspetto di C++ 0x, è possibile utilizzare std::is_empty da <type_traits>.

È specifica è:

T è un tipo di classe, ma non un tipo di unione, senza membri dati non statici non bit-campi di lunghezza 0, non funzioni membro virtuali, senza base virtuale classi e senza classe base B per cui is_empty<B>::value è false.

Non penso che ci sia un modo standard per scoprire se una classe è vuota per quanto riguarda il polimorfismo.

+0

come ho già commentato nella risposta di Konrad Rudolph, è possibile verificare se la classe è vuota quando è polimorfica. È necessario controllare 'is_polymorphic () && sizeof (T) == sizeof (some_polymorphic_class)'. Questo funzionerà con le classi polimorfiche sulla maggior parte dei compilatori. Non funzionerà solo per le classi con ereditarietà multipla. – UmmaGumma

+4

@Ashot: "sulla maggior parte dei compilatori" Di solito cerco di non pensare in termini di compilatori. :) – GManNickG

1

Facendo un passo sulla risposta di Konrad, questo gestisce le classi con o senza funzioni virtuali.

template <typename T> 
struct is_empty { 
    struct empty_ { virtual ~empty_(); }; 
    struct helper_ : T { virtual ~helper_(); }; 
    static bool const EMPTY = sizeof(helper_) == sizeof(empty_); 
}; 
+1

Ok, ma il puntatore alla tabella virtuale non è necessario sizeof (void *) (sembra errato, ad esempio, per Borland C++ a 16 bit che usa 2 byte puntatore "corto" per questo scopo indipendentemente dal modello di memoria). È meglio confrontare con sizeof (SomeEmptyPolimorphicClass) – user396672

+0

@user: si, buona idea. –

0

La risposta più semplice a questo che entrambe le opere ed è standard di denuncia: Guardate i file di intestazione per la classe/struct e la sua gerarchia di classe. Ti diranno se ci sono elementi di dati (oltre a un vtable).

Problemi correlati