编译时检查是否有两个具有相同模板参数的模板实例化
Compiletime check if there are two template instantiations with identical template-parameter
如果我有两个不相关的模板A
和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
如果每个参数类型都有一个唯一的 id(掩码(,因此我可以或所有掩码,看看 1 的数量是否等于 Checker
参数包的大小,这就可以工作。
此解决方案不好,因为客户端可能会忘记设置Checker
模板。
我想知道是否可以在引擎盖下进行更多检查?
此解决方案不好,因为客户端可能会忘记设置
Checker
模板。
良好的直觉 - 因此,您应该防止客户端在实例化Checker
之前实例化A
和B
。您可以通过将它们作为类型别名提供来实现此目的,只能从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>;
};
相关文章:
- 在 c++ 中的模板实例化中使用带有构造函数的类作为类型参数
- 如果模板参数是另一个模板的实例化,则键入特征测试
- 如何在模板函数中实例化其长度使用模板参数的数组
- 函数在可变参数模板的实例化期间不可见
- 实例化模板时,我是否必须显式显示参数包中的类型?
- 从模板参数包实例化的访问类实现
- C++ 可变参数模板实例化深度超过最大值 900
- 与参数匹配的友元模板函数实例化
- 有没有办法根据命令行参数定义数组大小?运行时与编译时实例化?
- 在编译时检查未实例化的类模板是否继承自其第一个模板参数
- 实例化模板参数的参数包
- SFINAE 和模板函数实例化:为什么在启用了 SFINAE 类型的函数参数中使用模板参数时无法推断模板参数?
- 非类型引用参数可以在运行时修改,这是否意味着模板可以在运行时实例化?
- 无法实例化抽象类,但类不是抽象/派生方法的参数
- 有没有办法将一对元组剥离为可变参数模板类型或实例化具有可变参数类型的东西?
- unique_ptr 使用尚未定义的参数进行实例化不会导致错误
- 根据运行时参数避免模板实例化的代码重复
- 编译时检查是否有两个具有相同模板参数的模板实例化
- 如何编写模板重载函数,并在模板参数不允许实例化某个类时触发回退
- 在不使用"new"的情况下实例化参数参数中的对象