接上篇:
利用类型,做函数模板的“重载”-CSDN博客
比较两种模板的写法
为什么左边不可行:

注意,左边的写法的第二个模板参数,是默认参数的形式。为何这里采取了默认参数的形式呢,本意是想让编译器来走sfine的流程,用户不用指明具体的类型。但就是这一点让最后的编译失败
当编译到test451(1);时,实例化成了
??$test451@HH@@YAXH@Z,也就是void __cdecl test451<int,int>(int)
template <typename Sequence, typename=int>
     void test451(Sequence x)
 {
     std::cout << "1" << std::endl;
 }
当编译到test451(1.0);时,按理说应该生成:void __cdecl test451<double,double>(double)
template <typename Sequence, typename=double>
     void test451(Sequence x)
 {
     std::cout << "1" << std::endl;
 }
但可能编译器不这么想,却给了一个“error C2995: “void test451(Sequence)”: 函数模板已经定义”的编译错误。明明void __cdecl test451<int,int>(int)和void __cdecl test451<double,double>(double)并不一样啊。
用C++ Insights分析
祭出C++ Insights吧,让它来分析分析下面的代码,看能否给出更多信息:
#include <cstdio>
#include <iostream>
#include <type_traits>template <typename Sequence, typename=typename std::enable_if<std::is_same<Sequence, int>::value, int >::type>void test451(Sequence x)
{std::cout << "1" << std::endl;
}template <typename Sequence, typename =typename std::enable_if<std::is_same<Sequence, double>::value, int >::type >void test451(Sequence x)
{std::cout << "1" << std::endl;
}template <typename Sequence, typename =typename std::enable_if<std::is_same<Sequence, std::wstring>::value, int >::type >void test451(Sequence x)
{std::cout << "1" << std::endl;
}int main()
{test451(1);test451(1.0);std::wstring str;test451(str);
}给出的结论如下:
/home/insights/insights.cpp:13:5: error: template parameter redefines default argument
    13 |     typename std::enable_if<std::is_same<Sequence, double>::value >::type>
       |     ^
意思是,在实例化double的情况的时候,提示默认参数被重定义了。
/home/insights/insights.cpp:6:5: note: previous default template argument defined here
     6 |     typename std::enable_if<std::is_same<Sequence, int>::value >::type>
       |     ^
之前实例化的在这里。(int版本)
/home/insights/insights.cpp:14:10: error: redefinition of 'test451'
    14 |     void test451(Sequence x)
       |          ^
 /home/insights/insights.cpp:7:10: note: previous definition is here
     7 |     void test451(Sequence x)
       |          ^
double版本的test451重新定义了int版本的test451。(所以报错)
果然是默认参数的问题。用int实例化的时候,默认参数是int,
/home/insights/insights.cpp:13:5: error: template parameter redefines default argument13 |     typename std::enable_if<std::is_same<Sequence, double>::value, int >::type >|     ^
/home/insights/insights.cpp:6:5: note: previous default template argument defined here6 |     typename std::enable_if<std::is_same<Sequence, int>::value, int >::type>|     ^
/home/insights/insights.cpp:14:10: error: redefinition of 'test451'14 |     void test451(Sequence x)|          ^
/home/insights/insights.cpp:7:10: note: previous definition is here7 |     void test451(Sequence x)|          ^
/home/insights/insights.cpp:28:5: error: no matching function for call to 'test451'28 |     test451(1);|     ^~~~~~~
/home/insights/insights.cpp:14:10: note: candidate template ignored: requirement 'std::is_same<int, double>::value' was not satisfied [with Sequence = int]14 |     void test451(Sequence x)|          ^
/home/insights/insights.cpp:29:5: error: no matching function for call to 'test451'29 |     test451(1.0);|     ^~~~~~~
/home/insights/insights.cpp:14:10: note: candidate template ignored: substitution failure [with Sequence = double, $1 = typename std::enable_if<std::is_same<double, double>::value, int>::type]14 |     void test451(Sequence x)|          ^
/home/insights/insights.cpp:32:5: error: no matching function for call to 'test451'32 |     test451(str);|     ^~~~~~~
/home/insights/insights.cpp:14:10: note: candidate template ignored: requirement 'std::is_same<std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t>>, double>::value' was not satisfied [with Sequence = std::wstring]14 |     void test451(Sequence x)|          ^
5 errors generated.
Error while processing /home/insights/insights.cpp.