gpt4 book ai didi

c++ - 为模板类静态实例生成有效标识符的宏

转载 作者:搜寻专家 更新时间:2023-10-31 01:32:50 24 4
gpt4 key购买 nike

背景

我正在研究 C++ 中的多态序列化和反序列化。为此,我使用静态 map :[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>因为 < , >不允许在标识符中使用。

问题

是否有一个很好的解决方法来实现以这种方式注册任意模板类型?

备选方案

我考虑了以下备选方案(每个都有缺点):

  • 运行时注册类型:看起来不够优雅,需要序列化用户付出更多努力;
  • RTTI:需要启用 RTTI,不保证不同类型将始终具有不同的哈希值/名称(当然不太可能,但仍然如此);
  • 要求用户提供类型别名或别名:不够优雅,序列化用户需要付出更多努力

更新:

  • 正如@Svalorzen 在他的回答中提到的,可以使用匿名命名空间。不幸的是,不能在翻译单元中多次使用宏是一个缺点。例如,对于仅 header 类型。

最佳答案

部分解决方案是始终使用相同的名称,但将其包装在未命名的命名空间中。这将只允许您为每个翻译单元注册一个类型,但这也许就足够了。

/// 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 .

关于c++ - 为模板类静态实例生成有效标识符的宏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42482894/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com