如果我有两个不相关的模板B
和P1
,如何执行编译时检查以查看是否存在两个相同的参数。例如。如果我有一些参数类型P2
和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
的解决方案,必须使用相关模板进行实例化:
Checker
如果每个参数typ都有唯一的id(掩码),那么这是有效的,因此我可以对所有掩码进行OR操作,看看1的数量是否等于Checker
参数包的大小。
此解决方案不好,因为客户端忘记来实例化{{1}}模板。
我想知道这项检查是否可以在引擎盖下进行更多的讨论?
答案 0 :(得分:2)
此解决方案不好,因为客户端可能忘记设置
Checker
模板。
良好的直觉 - 因此,在实例化A
之前,您应该阻止客户端实例化B
和Checker
。您可以通过提供仅从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;
如果您希望A
和B
是用户提供的,那么您可以将Checker
的类型别名作为模板 - 但这种方式会失败,因为用户已经首先访问A
和B
。
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>;
};