Нет, и он не будет работать надежно с typeid. Это даст вам некоторую внутреннюю строку, которая зависит от реализации компилятора. Что-то вроде «int», но также «i» является общим для int
.
Кстати, если вы хотите сравнить только два одинаковых типа, вам не нужно сначала преобразовывать их в строку. Вы можете просто сделать
template<typename A, typename B>
struct is_same { enum { value = false }; };
template<typename A>
struct is_same<A, A> { enum { value = true }; };
А потом
if(is_same<T, U>::value) { ... }
Boost уже имеет такой шаблон, и в следующем стандарте C ++ также будет std::is_same
.
Ручная регистрация типов
Вы можете специализироваться на следующих типах:
template<typename>
struct to_string {
// optionally, add other information, like the size
// of the string.
static char const* value() { return "unknown"; }
};
#define DEF_TYPE(X) \
template<> struct to_string<X> { \
static char const* value() { return #X; } \
}
DEF_TYPE(int); DEF_TYPE(bool); DEF_TYPE(char); ...
Итак, вы можете использовать его как
char const *s = to_string<T>::value();
Конечно, вы также можете избавиться от определения основного шаблона (и сохранить только предварительное объявление), если хотите получить ошибку времени компиляции, если тип неизвестен. Я просто включил его здесь для завершения.
Ранее я использовал статические данные-члены char const *, но они вызывают некоторые сложные проблемы, такие как вопросы о том, где их размещать, и так далее. Классовые специализации, как указано выше, решают проблему легко.
Автоматически, в зависимости от GCC
Другой подход заключается в использовании внутренних компонентов компилятора. В GCC следующее дает мне разумные результаты:
template<typename T>
std::string print_T() {
return __PRETTY_FUNCTION__;
}
Возвращаясь за std::string
.
std::string print_T() [with T = std::basic_string<char, std::char_traits<char>, std::allocator<char> >]
Некоторая магия substr
, смешанная с find
, даст вам строковое представление, которое вы ищете.