如何确定类型是否在编译时从模板类派生?

时间:2017-07-16 12:06:18

标签: c++ templates static-assert

说我有一些模板类:

template<class T>
class Foo{}

template<class T>
class Bar{}

现在,我想确保(在编译时)Bar中使用的类型来自Foo。我已经找到this回答,说明如何在运行时执行此操作,但我想在编译时检查,可能使用static_assert或其他东西。
有没有办法做到这一点?

1 个答案:

答案 0 :(得分:6)

  

现在,我想确保(在编译时)Bar中使用的类型来自Foo。

您可以这样做:

_id

wandbox上查看。
基本思想是,如果#include<type_traits> #include<utility> template<class T> class Foo{}; template<typename T> std::true_type test(const Foo<T> &); std::false_type test(...); template<class T> class Bar { static_assert(decltype(test(std::declval<T>()))::value, "!"); }; struct S: Foo<int> {}; int main() { Bar<S> ok1; Bar<Foo<int>> ok2; // Bar<int> ko; } 来自T的特化,无论const Foo<U> &是什么,您都可以将T类型的临时值绑定到Foo。因此,您可以声明(无需定义)一些函数,例如示例中的函数来测试它,然后在U或任何其他常量上下文中使用声明的返回类型。

修改

正如@Quentin在评论中所建议的那样,可能值得用指针替换引用,以防止转换构造函数和运算符出现误报。