2017-07-16 64 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