鉴于以下内容
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>::value是true, enable_if<T>::type是void,并且选择了专业化.但是,我的查询与以下情况下的选择有关.
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>::value是true作为::type是T代替void,因此不匹配主模板的默认值.
我的问题是标准中的哪个部分描述了选择模板的顺序,为什么实例test<T,void>被认为是更好的匹配test<T,T>.
完整样本:
#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)
在第一种情况下,您有类型
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 >::type是int。它不符合 a 作为 的类型typename Enable,要求为void
我的问题是标准中的哪个位置描述了选择哪个模板的顺序,以及为什么实例化被
test<T,void>认为是更好的匹配test<T,T>。
您编写了test<int>,这意味着您没有为第二个参数提供任何模板参数。因为它有一个默认参数,所以它被选择,所以你实际上有test<int, void>.
现在,根据上面链接的文本,模板参数与专业化相匹配。
在第一种情况下,专业化是test<int, void>在评估之后进行的,因此它是完全匹配和选择的。
在第二种情况下,专业化是test<int, int>在评估之后进行的,这不是完全匹配,因此选择主模板而不是该专业化。