[英]Macro generating a valid identifier for template-class static instance
我正在修补C ++中的多态序列化和反序列化。 为此,我使用静态映射: [type id-string] -> [type factory function]
。 每种类型都必须在此映射中注册,我想在编译时进行。
天真的方法是:
/// Creates a concrete serializable type provided as a template parameter
template <typename T>
ISerializable* createSerializable() { return new T; }
/// Factory that registers a serializable type T
template <typename T>
struct SerializableFactory
{
SerializableFactory(const char* type_name)
{
// registerType adds a type_name->factory_function entry to the map
registerType(type_name, createSerializable<T>);
}
};
通过宏注册类型:
/// Macro that registers the type at compile-time using a static factory instance
#define REGISTER_TYPE(T) \
static SerializableFactory<T> global_##T##Factory(#T);
例如REGISTER_TYPE(ArbitraryClass)
将变为:
static SerializableFactory<ArbitraryClass>
global_ArbitraryClassFactory("ArbitraryClass");
不幸的是,这对于ArbitraryClass<int>
不起作用,因为不允许在标识符中使用<
, >
。
是否有一个好的解决方法来实现以这种方式注册任意模板类型?
我考虑了以下替代方法(每种方法都有缺点):
更新:
一种部分解决方案是始终使用相同的名称,但将其包装在未命名的名称空间中。 这将只允许您为每个翻译单元注册一种类型,但这也许就足够了。
/// Macro that registers the type at compile-time using a static factory instance
#define REGISTER_TYPE(T) \
namespace { \
static SerializableFactory<T> serial_global_factory(#T); \
}
否则,您可以使用__LINE__
和__FILE__
宏标记为您的对象创建一个唯一的名称-只要您不必在其他任何地方引用它即可。 还有其他一些,可以在这里找到列表。
我有一个啊哈! 来自@WF的评论,@ Svalorzen答案和此答案的启发。 我相信这是一个聪明的把戏,没有其他选择的缺点。
解决方案:使用未命名/匿名名称空间并将 __LINE__
添加到标识符应始终提供唯一标识符(除非在同一行两次使用该宏)。
外观如下:
#define MERGE(A, B) A##B
#define CREATE_UNIQUE_IDENTIFIER(line) MERGE(unique_identifier_on_line_, line)
/// UNIQUE_IDENTIFIER generates identifiers like:
/// "unique_identifier_on_line_" + line_number
#define UNIQUE_IDENTIFIER CREATE_UNIQUE_IDENTIFIER(__LINE__)
/// Macro that registers the type at compile-time using a static factory instance
#define REGISTER_TYPE(T) \
namespace \
{ \
static SerializableFactory<T> UNIQUE_IDENTIFIER(#T); \
}
尝试将类型定义为单个名称并使用名称:
typedef ArbitraryClass<int> ArbitraryClass_int_;
REGISTER_TYPE(ArbitraryClass_int_);
您也可以尝试将其放在哈希映射中,其中的键是类型名。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.