c++ - instalar - Tiempo de compilación tipo ID sin RTTI con GCC
gcc que es (4)
En primer lugar, vuelva a activar RTTI.
Si falla, si realmente * realmente * necesita obtener una representación de cadena de un tipo sin él, con un poco de manipulación de cadena y una cuidadosa consideración del hecho de que está escribiendo un código no estándar que podría romperse si actualiza GCC, o cambie de plataforma, o use un conjunto diferente de opciones, podría ser capaz de falsificarlo.
#include <iostream>
#include <string>
std::string extract_type_name(const char* s) {
//add logic her
return s;
}
template<typename T>
std::string type_name() {
static std::string s = extract_type_name(__PRETTY_FUNCTION__);
return s;
}
int main() {
std::cout << type_name<int>() << " " << type_name<std::string>() << std::endl;
}
La salida de esa función en ideone es
std::string type_name() [with T = int]
std::string type_name() [with T = std::basic_string<char, std::char_traits<char>, std::allocator<char> >]
Suponiendo que __PRETTY_FUNCTION__
comporta de la misma manera con RTTI desactivado, extraer el bit T = blah
no debería ser demasiado difícil.
Además, tenga en cuenta que typeid(blah).name()
ofrece muy pocas garantías ... Recuerdo que lo typeid(blah).name()
en una plataforma donde el resultado para cualquier tipo definido por el usuario fue simplemente struct
. No demasiado útil. Confiar en él es endeble incluso con RTTI activado [lo que debería hacer de todos modos].
¿Hay typeid
obtener información de tipo typeid
de GCC con RTTI deshabilitado en tiempo de compilación? Bajo Visual Studio, un comando simple como const char* typeName = typeid(int).name();
devolverá apropiadamente "int", incluso si RTTI está deshabilitado. Desafortunadamente, GCC no puede hacer lo mismo. Cuando intento llamar a typeid
sin RTTI, mi programa falla. Sé que deshabilitar RTTI no es parte del estándar, pero ¿existe alguna forma en que pueda forzar a GCC a hacer una resolución de compilación de tipos conocidos?
RTTI está deshabilitado por razones de rendimiento. No tengo necesidad de RTTI en tiempo de ejecución.
Editar:
Esto es lo que terminé yendo con:
template<typename T> const char* TypeName(void);
template<typename T> const char* TypeName(T type) { return TypeName<T>(); }
#define REFLECTION_REGISTER_TYPE(type) /
template <> const char* TypeName<type>(void) { return #type; }
Requiere que se llame a REFLECTION_REGISTER_TYPE
para cada tipo que necesite información de reflexión. Pero mientras se llame para cada tipo requerido, llamar a TypeName<int>
funciona perfectamente. También agregué la función TypeName(T type)
que significa que puedes hacer cosas como esta: int x = 0; printf(TypeName(x));
int x = 0; printf(TypeName(x));
y se imprimirá "int". GCC debería ser capaz de hacer esto en tiempo de compilación como lo puede hacer VC ++.
GCC soporta operador de tipo de tiempo de compilación con typeof .
Hay otra solución con sus pros y sus contras:
typedef void* TypeId;
template<class T>
TypeId TypeIdNoRTTI() //this function is instantiated for every different type
{
//WARNING: works only inside one module: same type coming from different module will have different value!
static T* TypeUniqueMarker = NULL; //thus this static variable will be created for each TypeIdNoRTTI<T> separately
return &TypeUniqueMarker; //it''s address is unique identifier of TypeIdNoRTTI<T> type
}
No. RTTI es información de tipo de tiempo de ejecución (y deshabilitarla es una tontería, pero bueno), y ese es el propósito de typeid
. Si desea alinear nombres de tipo en tiempo de compilación, debe hacerlo usted mismo (mediante plantilla o macros).