我正在修改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>
因为<
,>
,uwsgi --http :8080 --home /home/flybegins/python/django/venv/ --chdir /home/flybegins/python/django/sample -w sample.wsgi
不允许在标识符中使用。
通过这种方式实现注册任意模板类型是否有良好的解决方法?
我考虑了以下备选方案(每种方案都有缺点):
更新
答案 0 :(得分:2)
部分解决方案是始终使用相同的名称,但将其包装在未命名的命名空间中。这只允许你为每个翻译单元注册一个类型,但这可能就足够了。
/// 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__
宏令牌为对象创建唯一名称 - 只要您不必在其他地方引用它。还有其他人,可以找到一个列表here。
答案 1 :(得分:1)
我有一个啊哈!时刻的灵感来自@ W.F的评论。 ,@ Svalorzen回答,this回答。我认为这是一个非常聪明的伎俩,没有替代方案的缺点。
解决方案:使用未命名/匿名命名空间 和 将__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); \
}
答案 2 :(得分:0)
尝试将类型定义为单个名称并使用名称:
typedef ArbitraryClass<int> ArbitraryClass_int_;
REGISTER_TYPE(ArbitraryClass_int_);
您也可以尝试将其放在哈希映射中,其中键是typename。