模板类特化enable_if和默认值

rma*_*son 5 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{};
Run Code Online (Sandbox Code Playgroud)

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

template <typename T,
    typename std::enable_if_t< some_trait<T>::value,T>::type >
struct test{};
Run Code Online (Sandbox Code Playgroud)

当为第二非空隙模板参数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;
}
Run Code Online (Sandbox Code Playgroud)

UmN*_*obe 5

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

std::enable_if< true, void >
Run Code Online (Sandbox Code Playgroud)

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

std::enable_if< true, int >
Run Code Online (Sandbox Code Playgroud)

std::enable_if< true, int >::typeint。它不符合 a 作为 的类型typename Enable,要求为void


Rak*_*111 2

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

[临时.等级.规格.匹配]

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

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

在第一种情况下,专业化是test<int, void>在评估之后进行的,因此它是完全匹配和选择的。

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