Typeid времени компиляции без RTTI с GCC - PullRequest
17 голосов
/ 04 ноября 2011

Есть ли способ получить информацию о времени компиляции typeid из GCC с отключенным RTTI?В Visual Studio простая команда, такая как const char* typeName = typeid(int).name();, соответственно возвращает «int», даже если RTTI отключен.К сожалению, GCC не может сделать то же самое.Когда я пытаюсь вызвать typeid без RTTI, моя программа падает.Я знаю, что отключение RTTI не является частью стандарта, но могу ли я в любом случае заставить GCC выполнять разрешение по времени компиляции известных типов?

RTTI отключен по соображениям производительности.У меня нет необходимости во время выполнения RTTI.

Редактировать:

Вот что я закончил:

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 должен действительно быть в состоянии сделать это во время компиляции, как VC ++.

Ответы [ 4 ]

5 голосов
/ 28 апреля 2014

Существует еще одно решение с его плюсами и минусами:

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
}
5 голосов
/ 04 ноября 2011

Прежде всего, включите 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 [что вы должны делать в любом случае].

5 голосов
/ 04 ноября 2011

Нет.RTTI - это RunTime Тип информации (и отключение его глупо, но эй), и это цель typeid.Если вы хотите структурировать имена типов во время компиляции, вы должны сделать это самостоятельно (с помощью шаблона или макроса).

1 голос
/ 04 ноября 2011

GCC поддерживает оператор типа времени компиляции с typeof .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...