gpt4 book ai didi

c++ - 类型的替代 id 生成器

转载 作者:IT老高 更新时间:2023-10-28 22:30:18 26 4
gpt4 key购买 nike

a project of mine , 我有一个 ID generator对于看起来与此类似的类型:

class Family {
static std::size_t identifier;

template<typename...>
static std::size_t family() {
static const std::size_t value = identifier++;
return value;
}

public:
template<typename... Type>
inline static std::size_t type() {
return family<std::decay_t<Type>...>();
}
};

std::size_t Family::identifier{};

用法:

const auto id = Family::type<FooBar>();

对于我的目的来说它工作得很好,但它有一些限制。最烦人的一个(问题的目的)是,如果所有链接到共享库的可执行文件都尝试创建标识符,它就会失败。结果通常是第 n 个标识符被跨边界分配给不同的类型,因为每个共享库都维护自己单独的 Family::identifier

一些共享库的人指出,更可靠的解决方案将不胜感激,但没有提出不会破坏性能的解决方案(几乎所有这些人都引入了容器、查找功能和内存分配)。

是否有任何替代方法可以解决上述限制而不会损失当前设计的性能?

我搜索了 SO 并找到了一些有趣的答案。其中许多已经有好几年了。只要现有类的接口(interface)保持不变,我想探索最新版本的标准的解决方案。
This one是最有趣的一个。它使用静态成员的地址来实现相同的目的,但它不符合顺序生成标识符的想法

注意:很遗憾,不能使用 RTTI。

注意 : ids 必须按顺序生成,从 0 开始,如上述解决方案。

最佳答案

您的问题出现是因为您的头文件中有这一行:

std::size_t Family::identifier{};

因此它最终出现在每个翻译单元中。相反,您需要将此存储移动到仅编译一次的 .cpp 源文件,可能会移动到它自己的共享库中。那么程序中将只有一个 identifier 实例,它会按您的意愿工作。

您还可以将 identifier 从一个类 static 变量移动到头文件中的全局 extern 变量(如上所述,定义它在一个 .cpp 文件中)。

如果你有 C++17 或更高版本,也可以试试:

inline std::size_t Family::identifier{};

虽然该语言不保证(甚至不提及)跨共享库边界使用此新功能时会发生什么,但它确实适用于我的机器。

关于c++ - 类型的替代 id 生成器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51332851/

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