Подтвердить что ты не робот

Компиляция типа typeid без RTTI с GCC

В любом случае, чтобы получить информацию о времени компиляции 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С++.

4b9b3361

Ответ 1

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

Ответ 2

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

Ответ 3

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

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
}

Ответ 4

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