2017-06-18 43 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<int>作为第一个模板参数和Alias为第二,那么编译器不会选择专业化。这立即给我们:

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

有了这个,我们可以 - 给出一些合适的模板参数 - 检测模板是否为别名模板或不:

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, ""); 
} 

这里的主要缺点是当然的那个人需要知道一组合适的模板参数。只是猜测(或使用int)将不适用于具有固定号码(> 1)模板参数的模板。

此外,这不适用于具有非类型(或模板)模板参数的模板(别名或不模板)。

相关问题