分析:两种不同的函数模板写法,其中一种为何不行

接上篇:

利用类型,做函数模板的“重载”-CSDN博客

主要原因,应该是这个:

模板的参数,必须给全。不管是隐式还是显式还是默认值-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吧,让它来分析分析下面的代码,看能否给出更多信息:

打开下面的链接

 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 argument
   13 |     typename std::enable_if<std::is_same<Sequence, double>::value, int >::type >
      |     ^
/home/insights/insights.cpp:6:5: note: previous default template argument defined here
    6 |     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 here
    7 |     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.

其他链接:

c++模板元编程std::enable_if详解-CSDN博客

  • 13
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值