2017-06-18 3 views
3

テンプレートがエイリアステンプレートであるかどうかを検出するにはどうすればよいですか? "通常" のテンプレートを考える

template<typename> struct Normal; 

とエイリアステンプレート:テンプレートテンプレートパラメータとして与えられたとき

template<typename> 
using Alias = void; 

は、どのように私は、これら二つを区別することができますか?

だから、理想的に、私は次のようにコンパイルしたい:

int main() { 
    static_assert( is_alias_template<Alias>::value, ""); 
    static_assert(! is_alias_template<Normal>::value, ""); 
} 

答えて

4

一つの可能​​なアプローチは、それを利用することである:テンプレートテンプレートを推定する際

エイリアステンプレートは、テンプレート引数控除により推定されることはありませんパラメータ。

http://en.cppreference.com/w/cpp/language/type_alias

したがって、

template< 
    typename T, 
    template<typename...> class Template 
    > 
struct instantiated_from 
    : std::false_type {}; 

template< 
    template<typename...> class Template, 
    typename... Arguments 
    > 
struct instantiated_from<Template<Arguments...>, Template> 
    : std::true_type {}; 

のようなタイプの形質に我々は最初のテンプレートパラメータと第二としてAliasとしてAlias<int>を渡すとき、コンパイラは選択しないことを確認することができます専門分野。

int main() { 
    static_assert( is_alias_template<Alias, int>::value, ""); 
    static_assert(! is_alias_template<Normal, int>::value, ""); 

    static_assert( is_alias_template<Alias, Alias<int>>::value, ""); 
    static_assert( is_alias_template<Alias, Normal<int>>::value, ""); 
    static_assert(! is_alias_template<Normal, Alias<int>>::value, ""); 
    static_assert(! is_alias_template<Normal, Normal<int>>::value, ""); 
} 

ここでの主な欠点はもちろんである: - 与えられたいくつかの適したテンプレート引数が - テンプレートはエイリアステンプレートであるかどうかを検出し、我々がすることができますこれにより

template< 
    template<typename...> class Template, 
    typename... Args 
    > 
struct is_alias_template 
    : std::integral_constant< 
     bool, 
     ! instantiated_from<Template<Args...>, Template>::value 
     > 
{}; 

:これはすぐに私たちを与えますそれは適切なテンプレート引数の集合を知る必要があるということです。ただ、テンプレートパラメータの固定数を持つテンプレート(1>)で、たとえば動作しません推測する(またはintを使用して)。

さらにこれは、(別名またはしない)非種類(またはテンプレート)テンプレートパラメータを持つテンプレートでは動作しません。

関連する問題