Ответ 1
Нет. RTTI - это RunTime Информация о типе (и отключить его глупо, но эй), и цель typeid
. Если вы хотите привязать имена типов во время компиляции, вы должны сделать это самостоятельно (через шаблон или макросы).
В любом случае, чтобы получить информацию о времени компиляции typeid
от GCC с отключенным RTTI? В Visual Studio простая команда типа const char* typeName = typeid(int).name();
будет соответствующим образом возвращать "int", даже если RTTI отключен. К сожалению, GCC не может сделать то же самое. Когда я пытаюсь вызвать typeid
без RTTI, моя программа выйдет из строя. Я знаю, что отключение RTTI не является частью стандарта, но все равно я могу заставить GCC выполнить компиляцию временного разрешения известных типов?
RTTI отключен по соображениям производительности. Мне не нужна RTTI времени выполнения.
Edit:
Вот что я закончил:
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; }
Это требует, чтобы REFLECTION_REGISTER_TYPE
вызывался для каждого типа, который нуждается в информации отражения. Но до тех пор, пока он требует для каждого требуемого типа, вызов TypeName<int>
работает отлично. Я также добавил функцию TypeName(T type)
, что означает, что вы можете делать такие вещи: int x = 0; printf(TypeName(x));
и распечатывать "int". GCC должен действительно быть в состоянии сделать это во время компиляции, например, VС++.
Нет. RTTI - это RunTime Информация о типе (и отключить его глупо, но эй), и цель typeid
. Если вы хотите привязать имена типов во время компиляции, вы должны сделать это самостоятельно (через шаблон или макросы).
Прежде всего, вернитесь к RTTI.
Если это действительно так, если вы действительно * действительно хотите получить строковое представление типа без него, с небольшими манипуляциями с строкой и тщательным рассмотрением того факта, что вы пишете нестандартный код, который может сломаться, если вы обновить GCC или изменить платформы или использовать другой набор параметров, вы можете подделать его.
#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;
}
Выход этой функции на ideone равен
std::string type_name() [with T = int]
std::string type_name() [with T = std::basic_string<char, std::char_traits<char>, std::allocator<char> >]
Предполагая, что __PRETTY_FUNCTION__
ведет себя одинаково с выключенным RTTI, извлечение бит T = blah
не должно быть чрезмерно трудным.
Кроме того, имейте в виду, что typeid(blah).name()
предлагает очень мало гарантий... Я помню, как использовать его на одной платформе, где результат для любого пользовательского типа был просто struct
. Не слишком полезно. Опираясь на это непросто даже с включенным RTTI [который вы должны делать так или иначе].
Есть еще одно решение с его плюсами и минусами:
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 address is unique identifier of TypeIdNoRTTI<T> type
}
GCC поддерживает оператор типа времени компиляции с typeof.