2017-07-16 10 views
2

は、私はいくつかのテンプレートクラスを持っていると言う:コンパイル時に型がテンプレートクラスから派生しているかどうかを調べる方法は?

template<class T> 
class Foo{} 

template<class T> 
class Bar{} 

は今、私はBarで使用されるタイプがFooから派生していること(コンパイル時に)を確認します。私はすでに実行時にそれを行う方法を示すthis答えを見つけましたが、コンパイル時にstatic_assertなどを使用してチェックしたいと思います。
これを行う方法はありますか?

+1

使用できる[型特質](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でそれを参照してください:

あなたはこのような何かを行うことができます。
のタイプを一時的ににバインドすることができます。具体的には、がFooの特殊化に由来する場合は、Uになります。したがって、テストするサンプルのようないくつかの関数を宣言(定義不要)してから、static_assertまたは他の定数コンテキストで宣言された戻り型を使用することができます。


編集

コメントで@Quentinによって示唆されるように、おそらくそれは、変換コンストラクタと演算子から偽陽性を防ぐために、ポインタと参照を交換する価値があります。

+4

これはFooの正確なFoo、OP want subtypeをチェックします。 –

+0

@yurikilochek右。派生クラスの一致を修正しました。 – skypjack

+0

私は変換のコンストラクタと演算子からの誤検出を防ぐために、参照をポインタで置き換えます。 – Quentin