una tamaño funciones estructuras estructura ejemplos datos con arreglo anidadas c++ inheritance c++17 typetraits

tamaño - Con C++ 17, ¿es posible detectar si una estructura/clase tiene alguna base?



funciones con estructuras en c (2)

Necesito un rasgo de tipo que será verdadero si el tipo dado se deriva de algo, y falso de lo contrario.

Por ejemplo:

template<class T> struct is_inherit //... logic of inheritance detection ; template<class T> void AppLogic(){ if constexpr(is_inherit<T>::value) { puts("T has base"); //... } else { puts("T doesn''t have base"); //... } } struct A {}; struct C {}; struct B: C {}; int main() { AppLogic<A>(); // print: T doesn''t have base AppLogic<B>(); // print: T has base }

¿Es posible de alguna manera implementar esa estructura de rasgo "is_inherit"?

¿Por qué?

Estoy desarrollando un generador manual de cuadernos de pila para Windows x64. Según la https://docs.microsoft.com/en-us/cpp/build/return-values-cpp documentación, si es un tipo:

  • tiene una longitud de 1, 2, 4, 8, 16, 32 o 64 bits;
  • no tiene ningún operador de asignación de copia, destructor o constructor definido por el usuario;
  • no tiene miembros de datos no estáticos ni protegidos ni privados;
  • no tiene miembros de datos no estáticos de tipo de referencia;
  • no tiene clases base;
  • no tiene funciones virtuales;
  • y no tiene miembros de datos que tampoco cumplan con estos requisitos;

entonces su valor de retorno está en el registro RAX; de lo contrario, la función tiene un argumento oculto que debo detectar y manejar.

Esta solía ser la definición de un C ++ 03 POD, sin embargo en C ++ 11 esto cambió:

Debido a que la definición ha cambiado en el estándar C ++ 11, no recomendamos utilizar std::is_pod para esta prueba.

Hasta ahora, con algunos rasgos conjugados podía detectar si el tipo cumplía con la definición de C ++ 03 POD o no. Sin embargo, con C ++ 17 las reglas agregadas han cambiado, y eso rompió mi solución.

Si de alguna manera puedo detectar si un tipo T tiene alguna clase base, mi solución funcionará nuevamente.


Creo que no es posible verificar si " T deriva de algo", al menos no de una manera estándar. Si está utilizando esta técnica para verificar si un tipo es un POD / trivial / agregado, existen algunos rasgos de tipo que pueden ayudarlo:


Sí, esto es posible, al menos para agregados.

Primero construimos una plantilla de clase que es convertible a cualquier base adecuada de su parámetro de plantilla:

template<class T> struct any_base { operator T() = delete; template<class U, class = std::enable_if_t<std::is_base_of_v<U, T>>> operator U(); };

Luego detectamos si un parámetro de plantilla T es any_base<T> construible a partir de un valor de tipo any_base<T> :

template<class, class = void> struct has_any_base : std::false_type {}; template<class T> struct has_any_base<T, std::void_t<decltype(T{any_base<T>{}})>> : std::true_type {};

Example .