c++ - 编译时检查是否有两个具有相同模板参数的模板实例化

标签 c++ templates c++17

如果我有两个不相关的模板AB ,如何执行编译时检查以查看是否有两个相同的参数。例如。如果我有一些参数类型 P1P2 ,我想让客户端实例化A<P1>B<P2>但不是 A<P1>B<P1> .

我有一个使用可变参数模板的解决方案 Checker<typename... Xx>必须使用相关模板实例化:

using a = A<P1>;
using b = B<P1>;
using checker = Checker<a, b>;

checker::init(); // can be empty
                 // static_assert fails here

如果每个参数 typ 都有一个唯一的 id(掩码),这就有效,因此我可以对所有掩码进行 OR,看看它们的数量是否等于 Checker 的参数包的大小。 .

这个解决方案不好,因为客户端可能忘记实例化 Checker模板。

我想知道是否可以在后台进行更多检查?

最佳答案

This solution is not good because a client can forget to instatiate the Checker template.

良好的直觉 - 因此,您应该阻止客户端在实例化 Checker 之前实例化 AB。您可以通过将它们提供为只能从 Checker 访问的类型别名 来实现这一点。

namespace detail
{
    template <typename T> struct A;
    template <typename T> struct B;
}

template <typename P0, typename P1>
struct Checker
{
    static_assert(!std::is_same_v<P0, P1>);

    using A = detail::A<P0>;
    using B = detail::B<P1>;
};

用法:

using ClientABProvider = ABProvider<foo, bar>;
using A = typename ClientABProvider::A;
using B = typename ClientABProvider::B;

using ClientABProvider = ABProvider<foo, foo>; // Error!
using A = typename ClientABProvider::A;
using B = typename ClientABProvider::B;

如果您希望AB 由用户提供,您可以将Checker 的类型别名作为模板——但是这种由于用户已经首先访问了 AB,因此无法实现其目的。

template <typename P0, typename P1>
struct Checker
{
    static_assert(!std::is_same_v<P0, P1>);

    template <template <typename> class XA>
    using A = XA<P0>;

    template <template <typename> class XB>
    using B = XB<P1>;
};

关于c++ - 编译时检查是否有两个具有相同模板参数的模板实例化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44502198/

相关文章:

c++ - C++智能指针能否完全封装其数据?

c++ - 面向 OpenGL 2.0

c++ - 不同翻译单元中的内联静态变量具有不同的值(c++17)

c++ - 我可以将 std::any 与 C++17 一起用于指向成员变量的指针吗?

c++ - std::vector 和 std::list 的重载运算符

c++ - 从从左到右读取的所有类型创建嵌套包

c++ - 如何在另一个结构中使用一个结构?

c++ - 使用 C++ 在 OpenCV 中按深度维度排序

c++ - 使用元编程递归初始化 std::array

javascript - 使用模板但保留 jquery 绑定(bind)?