¿Existe una manera fácil de saber si una clase/estructura no tiene miembros de datos?
Hola,
¿Existe alguna forma sencilla en C++ de saber (en tiempo de compilación) si una clase/estructura no tiene miembros de datos?
P.ejstruct T{};
Lo primero que pensé fue comparar sizeof(T)==0
, pero siempre parece ser al menos 1.
La respuesta obvia sería simplemente mirar el código, pero me gustaría activar esto.
Desde C++ 11, puedes usar el std::is_empty
rasgo .
Si sigue una dieta paleocompiladora, puede utilizar la implementación Boost.TypeTraits deis_empty
. Se basa en la optimización de base vacía , que realizan todos los compiladores de C++ convencionales y garantiza que una clase base vacía no ocupe espacio en una clase derivada.
La implementación de Boost.TypeTraits utiliza una clase auxiliar que se deriva de la clase que el usuario desea probar y que tiene un tamaño fijo y conocido. Un resumen aproximado de la lógica es el siguiente:
template <typename T>
struct is_empty {
struct helper : T { int x; };
static bool const VALUE = sizeof(helper) == sizeof(int);
};
Sin embargo, tenga en cuenta que la implementación real de Boost es más compleja ya que necesita tener en cuenta funciones virtuales (todos los compiladores convencionales de C++ implementan clases con funciones virtuales agregando un miembro de datos invisible para la tabla de funciones virtuales a la clase). ¡Por lo tanto, lo anterior no es suficiente para implementarlo is_empty
correctamente!
Si su compilador admite este aspecto de C++0x, puede utilizar std::is_empty
desde <type_traits>
.
Su 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, sin funciones miembro virtuales, sin clases base virtuales y sin clase baseB
para la cualis_empty<B>::value
esfalse
.
No creo que exista una forma estándar de saber si una clase está vacía con respecto al polimorfismo.
Siguiendo la respuesta de Konrad, esto 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_);
};