模板类专门化enable_if和默认值

时间:2018-06-06 13:44:33

标签: c++ c++11

鉴于以下内容

template <typename T, typename Enable=void>
struct test{};

template <typename T,
    typename std::enable_if< some_trait<T>::value >::type >
struct test{};

假设some_trait<T>::valuetrueenable_if<T>::typevoid,并且选择了专门化。 但是,我的查询与以下情况下的选择有关。

template <typename T,
    typename std::enable_if_t< some_trait<T>::value,T>::type >
struct test{};

enable_if提供::type的第二个非空模板参数时,非专业化模板 已被选中,即使some_trait<T>::valuetrue::typeT而不是void,因此不会 匹配主模板中的默认值。

我的问题是标准中的哪个位置描述了选择模板的顺序,以及为什么 实例test<T,void>被认为是更好的匹配,然后是test<T,T>

https://ideone.com/7v4TTS

完整样本:

#include <iostream>
#include <type_traits>

template <typename T,typename Enable=void>
struct test
{
    const char* value = "Primary";
};

#if 1// toggle this

template <typename T>
struct test<T,typename std::enable_if< std::is_same<T,T>::value >::type > 
{
    const char* value = "Specialization";
};

#else

template <typename T>                                    
struct test<T,typename std::enable_if< std::is_same<T,T>::value,T >::type> 
{                                                          ///  ^    
    const char* value = "Specialization";
};

#endif

int main() {
    test<int> v;
    std::cout << v.value << std::endl;
    return 0;
}

3 个答案:

答案 0 :(得分:3)

在第一种情况下,您有类型

std::enable_if< true, void >

在第二种情况下,你有类型

std::enable_if< true, int >

std::enable_if< true, int >::typeint。它不符合要求typename Enable

void的类型

答案 1 :(得分:2)

test<int> v;test<int, void> v;(感谢默认类型)。

test<int, int> v;会选择您的上一次专业化。

答案 2 :(得分:1)

  

我的问题是标准中的哪个位置描述了选择哪个模板的顺序,以及为什么将实例test<T,void>视为比test<T,T>更好的匹配。

[temp.class.spec.match]

您编写了test<int>,这意味着您没有为第二个参数提供任何模板参数。因为它有一个默认参数,所以选择它,所以实际上你有test<int, void>

现在,根据上面链接的文本,模板参数与专业化相匹配。

在第一种情况下,评估后专业化为test<int, void>,因此它是精确匹配并被选中。

在第二种情况下,评估后的专业化为test<int, int>,这不是完全匹配,因此选择主要模板而不是专业化。