мне нужно каталогизировать все классы, используемые в проекта, так что эти классы могут быть создан на лету из внутри завода [...]
Недостаточно использовать RTTI (это не плохая идея, если вам это разрешено; boost :: any делает это), как насчет просто использования строки для имен классов? Вы можете получить это через макрос.
#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;
}
Наилучшая вещь с таким подходом заключается в том, что вам не нужно беспокоиться о проблемах между единицами перевода или модулями при таком подходе. Единственное, на что вы должны обратить внимание, это конфликты имен, и в этом случае вы можете указать пространство имен, чтобы избежать их («std :: string», а не просто «строка», например).
Мы используем это решение как альтернативу boost :: любому, который мы предоставляем через наш SDK (и, следовательно, не можем использовать boost, так как это потребует от наших пользователей установки с повышением или для доставки части ускорения, в котором это может привести к конфликтам для пользователей, у которых установлены разные версии boost). Это не так автоматизировано, как boost :: any, поскольку для этого требуется ручная регистрация поддерживаемых типов (ближе к boost :: variant в этом отношении), но не требует, чтобы наши пользователи SDK включали RTTI и работали переносимо через границы модулей (I ' m не уверен, что можно полагаться на RTTI для получения одинаковой информации в разных компиляторах, настройках и модулях - я сомневаюсь в этом).
Теперь вы можете использовать эти идентификаторы строк, которые вам нравятся. Одним из примеров было бы использовать его для сопоставления функций создания с этими идентификаторами строк, чтобы вы могли создать экземпляр std :: string, например, через factory :: create («std :: string»); Обратите внимание, что это гипотетический случай для демонстрационных целей только потому, что использование фабрики для создания std :: string будет довольно странным.
Какой проблемы вы пытаетесь решить? Я никогда не видел хорошего использования макроса счетчика, который требует уникальных идентификаторов за пределами отдельной единицы перевода. –
Мне нужно каталогизировать все классы, используемые в проекте, поэтому эти классы можно создавать «на лету» с завода, тем самым единственным решением, которое я получил, было объявление переменной класса значений, которая при ее инициализации добавила бы этот новый класс объявление в заводском списке, и все это динамично, программист, использующий lib, должен просто объявить класс, используя препроцессор, который будет автоматически каталогизироваться и может использоваться на лету после – Jonathan
. Как насчет ((md5sum (\ __ FILE__) + __ LINE__)? (Заполните ваш любимый алгоритм хеш-кода для строк вместо md5sum, если хотите) –