Я не уверен, применимо ли это в вашем случае (если ваш вопрос конкретно касается механизмов повышения или нет), но как насчет строк? Я не знаю, как это возможно, но я применил такое решение к нашей базе кода:
#include <iostream>
#include <string>
using namespace std;
template <class T>
const char* my_type_id()
{
return "Unknown";
}
#define REGISTER_TYPE(some_type) \
template <> inline \
const char* my_type_id<some_type>() \
{ \
return #some_type; \
}
REGISTER_TYPE(int)
REGISTER_TYPE(std::string)
int main()
{
// displays "int"
cout << my_type_id<int>() << endl;
// displays "std::string"
cout << my_type_id<string>() << endl;
// displays "Unknown" - we haven't registered char
cout << my_type_id<char>() << endl;
}
Это в основном переизобретение RTTI, которое, если вы можете использовать его для производственных сборок, делает это решение ненужным. Мы не могли сделать это, как это было для комплекта разработки программного обеспечения, и мы не хотели предполагать, что у всех, кто его использует, будет включен RTTI.
Если вам нужны целые числа вместо строк, то это достаточно легко адаптировать:
template <class T>
int my_type_id()
{
return -1;
}
#define REGISTER_TYPE(some_type, type_code) \
template <> inline \
int my_type_id<some_type>() \
{ \
return type_code; \
}
REGISTER_TYPE(int, 1234)
REGISTER_TYPE(std::string, 4567)
Вы могли бы даже избежать издержек при вызове функции и просто создать класс, который хранит эти интегральные значения, связанные с типом, как перечисляемую константу (гарантированно будет значением r).