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

Mas*_*rem 2 c++ templates static-assert

说我有一些模板类:

template<class T>
class Foo{}

template<class T>
class Bar{}
Run Code Online (Sandbox Code Playgroud)

现在,我想确保(在编译时)使用的类型Bar派生自Foo.我已经找到了这个答案,展示了如何在运行时这样做,但我想在编译时检查,也许使用static_assert或者其他东西.
有没有办法做到这一点?

sky*_*ack 6

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

你可以这样做:

#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;
}
Run Code Online (Sandbox Code Playgroud)

wandbox上看到它.
基本思想是你可以绑定一个临时类型T,const Foo<U> &如果T是从一个特化派生的Foo,无论是什么U.因此,您可以声明(无需定义)一些函数,例如示例中的函数来测试它,然后在一个static_assert或任何其他常量上下文中使用声明的返回类型.


编辑

正如意见建议的@Quentin,或许这是值得的指针代替引用防止误报的转换构造和运营商.

  • 这检查确切的Foo,OP想要Foo的子类型. (4认同)