2011-01-28 8 views
15

Hallo,¿Hay una manera fácil de saber si una clase/estructura no tiene miembros de datos?

¿Hay alguna manera fácil en C++ de decir (en tiempo de compilación) si una clase/estructura no tiene miembros de datos?

E.g. struct T{};

Mi primer pensamiento fue comparar sizeof(T)==0, pero esto siempre parece ser al menos 1.

La respuesta obvia sería la de simplemente mirar el código, pero me gustaría cambiar en esto.

+4

¿calificaría una tabla v como miembro de datos? Es una especie de oculta. – CashCow

+0

'sizeof (T) == 0' parece existir en D, pero está prohibido por el estándar de C++, correcto. –

+0

¿Por qué quieres hacer esto? –

Respuesta

13

Puede derivar de esta clase en otro vacío y comprobar si sizeof(OtherClass) == 1. Boost lo hace en su rasgo de tipo is_empty.

No comprobado:

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

Sin embargo, esto se basa en la optimización de la clase base vacía (pero todos los compiladores modernos hacer esto).

+2

No funcionará. Como CashCow dice que esto no funcionará para las clases con función virtual. – UmmaGumma

+3

@Ashot: No debería ser "no va a funcionar" tanto como "no funcionará dado algunas definiciones de vacío". – GManNickG

+0

@Ashot Martirosyan ... pero la solución puede modificarse derivando de alguna clase auxiliar básica con función virtual ficticia y también de la clase que se está probando – user396672

11

Si su compilador admite este aspecto de C++ 0x, puede usar std::is_empty desde <type_traits>.

Es especificación es:

T es un tipo de clase, pero no un tipo de unión, sin miembros de datos no estáticos distintos de los campos de bits de longitud 0, no hay funciones miembro virtuales, no base virtual clases, y ninguna clase base B para la cual is_empty<B>::value es false.

No creo que haya una manera estándar de encontrar si una clase está vacía con respecto al polimorfismo.

+0

como ya comenté en la respuesta de Konrad Rudolph, es posible verificar si la clase está vacía cuando es polimórfica. Debes marcar 'is_polymorphic () && sizeof (T) == sizeof (some_polymorphic_class)'. Esto funcionará para clases polimórficas en la mayoría de los compiladores. No funcionará solo para las clases con herencia múltiple. – UmmaGumma

+4

@Ashot: "en la mayoría de los compiladores" Normalmente trato de no pensar en términos de compiladores. :) – GManNickG

1

Siguiendo la respuesta de Konrad, maneja clases con o sin funciones virtuales.

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

Bien, pero el puntero a la tabla virtual no es necesario sizeof (void *) (parece incorrecto, por ejemplo, para Borland C++ de 16 bits que usa 2 bytes de puntero "corto" para este propósito independientemente del modelo de memoria). Es mejor comparar con sizeof (SomeEmptyPolimorphicClass) – user396672

+0

@user: sí, buena idea. –

0

La respuesta más simple a esto que funciona y es una queja estándar: Mire los archivos de encabezado para la clase/estructura y su jerarquía de clases. Ellos le dirán si hay elementos de datos (además de un vtable).

Cuestiones relacionadas