我需要对项目中使用的所有类进行编目,因此可以在工厂中动态创建这些类 [...]
没有使用 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”,而不是简单的“string”,例如)。
我们将此解决方案用作我们通过 SDK 提供的 boost::any 的替代方案(因此不能使用 boost,因为它需要我们的用户安装 boost 或让我们运送部分 boost,在这种情况下它可能会导致对于安装了不同版本的 boost 的用户的冲突)。它不像 boost::any 那样自动,因为它需要手动注册支持的类型(在这方面更接近 boost::variant),但不需要我们的 SDK 用户启用 RTTI 并且可以跨模块边界可移植地工作(I'我不确定是否可以依赖 RTTI 在不同的编译器、设置和模块中生成相同的信息——我对此表示怀疑)。
现在,您可以随意使用这些类型关联的字符串 ID。一个示例是使用它将创建函数映射到这些字符串 ID,以便您可以创建 std::string 的实例,例如,通过 factory::create("std::string"); 请注意,这只是出于演示目的的假设情况,因为使用工厂创建 std::string 会很奇怪。