gpt4 book ai didi

c++ - 编译时检查 trait specialization 是否有唯一的 id

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:32:42 24 4
gpt4 key购买 nike

我看过很多解释如何为类生成唯一 ID 的帖子。

在我的例子中,id 是由用户选择的(出于各种原因),但我想确保没有 id 在不同的类中被使用两次。

我将我的问题简化为以下代码:

struct A {}; struct B {};

template <typename T> struct traits {};
template <> struct traits<A> { static constexpr size_t id() { return 0; }}
template <> struct traits<B> { static constexpr size_t id() { return 1; }}

现在,有没有一种简单的方法可以确保有人不会添加具有重复 id 的特性的特化:

struct C {};
template <> struct traits<C> { static constexpr size_t id() { return 1; // this should static_assert ! }}

我可以使用 C++11,我不想滥用预处理器。

如果可能,该解决方案不应要求专门化特征的代码有任何特殊之处(即,如果检查可以通过查看现有的专门化在外部完成,那就太好了)。

谢谢

最佳答案

这是一个想法,我不确定它是否适用于您:

#include <cstddef>

struct A {}; struct B {}; struct C {};

template <size_t Id> constexpr size_t getId() { return Id; }

template <typename T> struct traits {};

template size_t getId<0>();
template <> struct traits<A> { static constexpr size_t id() { return getId<0>(); }};

template size_t getId<1>();
template <> struct traits<B> { static constexpr size_t id() { return getId<1>(); }};

/* This fails to compile
template size_t getId<1>();
template <> struct traits<C> { static constexpr size_t id() { return getId<1>(); }};
*/

int main() { return 0; }

这依赖于使用函数的显式模板实例化。很明显,陷阱是你可能忘记添加这个实例化而仍然使用这个函数,那么它就不会编译失败。您可以定义一些预处理器宏以确保始终使用它定义特征。


编辑:正如 Oliv 所指出的那样,上述解决方案仅在所有模板实例化发生在同一翻译单元中时才有效。此版本跨编译单元工作,但更容易出错(模板参数和返回值必须匹配)。

#include <cstddef>

struct A {}; struct B {}; struct C {};

template <size_t Id> constexpr size_t getId();

template <typename T> struct traits {};

template <> constexpr size_t getId<0>() { return 0; }
template <> struct traits<A> { static constexpr size_t id() { return getId<0>(); }};

template <> constexpr size_t getId<1>() { return 1; }
template <> struct traits<B> { static constexpr size_t id() { return getId<1>(); }};

/* This fails to compile
template <> constexpr size_t getId<1>() { return 1; }
template <> struct traits<C> { static constexpr size_t id() { return getId<1>(); }};
*/

int main() { return 0; }

编辑 2:我发布了问题 Why does explicit template instantiation not break ODR?由于我在撰写此答案时发现的行为令人惊讶。有关可能无法编译或可能无法编译的内容的更多详细信息,请参阅此处。

关于c++ - 编译时检查 trait specialization 是否有唯一的 id,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52644921/

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