2017-05-11 8 views
4

を通じて継承するテンプレートクラスを検出するメタ関数は、私はこのようなものですインターフェイスを持ってCRTP

template<typename T> 
class Concrete : public Interface<Concrete<T>, T> 
{ 
    ... 
    using type = typename T; 
} 

私がチェックできるメタ関数を持っていると思いますあるタイプがInterfaceから来るかどうか。一例として、

、のインターフェイスが唯一のテンプレート引数を持っていた(それゆえ、それは子供のテンプレートクラスを生成しない)としましょう:

template<typename Concrete> 
class A 
{ 
    ... 
} 

class B : public A<B> 
{ 
    ... 
} 

この場合、私が使用できます。

template<typename T> 
struct is_A 
{ 
    static bool const value = std::is_base<A<T>, T>::value; 
} 

私の質問は、追加のテンプレート引数がある場合のための同様のメタ機能を生成する最良の方法は何ですか?明確にするため

template<typename T>  
struct is_Interface{} 

、私は

template<template <class> class T>  
struct is_Interface 
{ 
    using dummy_type = void; 
    static bool const value = std::is_base<Interface<T<dummy_type>, dummy_type>, T<dummy_type>>::value; 
} 

を作り出すことができるが、私は、私は具体的な形ではなくテンプレートクラスを渡す何かをしたいと思います。それは次のようになります。

答えて

4

あなたがオーバーロードの解決を利用することができます:

template <template <class> class Concrete, class T> 
std::true_type is_Interface_impl(Interface<Concrete<T>, T> *); 

std::false_type is_Interface_impl(...); 

template<typename T> 
struct is_Interface : decltype(is_Interface_impl(std::declval<T*>())) { }; 
ポインタの変換はテンプレート引数控除で許可されている派生ツーベース

が、それはis_Interface_implの最初の過負荷が検出し、関係を一致させることができる方法です。変換が実行できない場合、SFINAEが適用され、オーバーロードの解決がvararg関数に戻ります。

See it live on Coliru!

+0

これは本当にクールで、私の場合はうまくいきます!本当にありがとう – JosephK

関連する問題