2017-07-16 71 views
2

说我有一些模板类:如何确定类型是否在编译时从模板类派生?

template<class T> 
class Foo{} 

template<class T> 
class Bar{} 

现在,我要确保(在编译时),在Bar使用的类型从Foo的。我已经找到this答案,说明如何在运行时做到这一点,但我想在编译时检查,也许使用static_assert什么的。
有没有办法做到这一点?

+1

可能有一些[type-traits](http://en.cppreference.com/w/cpp/types#Type_traits_.28since_C.2B.2B11.29)可以使用。 –

+1

@Someprogrammerdude是的,我研究了一下。 is_base_of可能工作,但我只知道如何使用它时,Foo是一个普通的类而不是模板类。 – Mastrem

回答

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; 
} 

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


编辑

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

+4

这会检查Foo,OP是否需要Foo的子类型。 –

+0

@yurikilochek对。修复以匹配派生类。 – skypjack

+0

我想用一个指针来替换引用,以防止转换构造函数和运算符产生误报。 – Quentin