模板和专用模板如何

时间:2012-11-03 08:19:50

标签: c++ template-specialization

这是我不理解的代码

#include<iostream>

using namespace std;

template <typename T> 
T calc(T, T) { cout << "template calc" << endl; }

double calc(double, double) { cout << "ordinary calc" << endl; }

template <> 
char calc<char>(char, char) { cout << "template specialisation calc" << endl; }

int main() {

   int ival;
   double dval;
   float fd;

   calc(0, ival); // calls the generic calc(T, T)

   // the following all call calc(double, double)
   calc(0.25, dval);
   calc(0, fd);
   calc(0, 'J');

   calc('I', 'J'); // calls calc(char, char)
}

有5个函数调用calc,所以我会根据它们的位置将它们称为1) - 5)。

1)有道理。 0是整数,ival是整数,有意义的是调用calc(T,T)。虽然我觉得我的理由是错误的。毕竟,它们都是双打的,所以如果调用calc(double,double),那也是有意义的。所以在这里寻求澄清。

2)没有戏剧,都是双打,叫钙(双,双)。简单。

3)fd是一个浮点数。可以调用calc(T,T)或calc(double,double)。因为1)导致对calc(T,T)的调用,我会假设同样会在这里保持,因为我们再次有一个param为0,但是,这会调用calc(double,double)。所以这让我感到困惑,尤其是这与1)之间的区别

4)我的第一个想法是0是一个有效的字符,所以是'J',所以它调用calc(char,char)。它可以使用常见的整数类型调用calc(T,T)。但是没有,两个都错了,它叫做calc(double,double)。我对此非常困惑。对我毫无意义。

5)有意义,但只有我应用了与4)相同的逻辑,这在4)中是错误的,所以如果我要看到另一个使用模板的例子,我不确定是什么逻辑申请。

所以寻找解释为什么这个程序能做它的功能。

感谢。

2 个答案:

答案 0 :(得分:1)

首先,当您在源代码中写入文字“0”时,它的类型为“int”。在查找要调用的函数时,编译器会选择最匹配的函数。如果不可用,编译器将执行一些隐式类型转换以使其工作。

1)0和ival都是int

2)对于double和double,calc(double,double)完全匹配

3)对于int和float,未找到匹配,因此两者都转换为double

4)对于int和char,与3)相同

5)对于char和char,calc(char,char)完全匹配

答案 1 :(得分:1)

我建议你阅读overload resolution

  

选择最合适的重载函数或运算符的过程称为重载解析。

     

假设f是一个重载的函数名。当你打电话给   重载函数f(),编译器创建一组候选   功能。这组函数包括所有名为f的函数   可以从您调用f()的位置访问。编译器   可以包括作为候选函数的替代表示   其中一个名为f的可访问函数,以方便过载   分辨率。

     

创建一组候选函数后,编译器会创建一个   一套可行的功能。这组函数是其中的一个子集   候选职能。每个可行功能的参数数量   同意你用来调用f()的参数数量。

     

编译器选择最好的可行功能,即功能   声明C ++运行时环境将在您调用时使用   f(),来自可行功能集。编译器执行此操作   隐式转换序列。隐式转换序列是   转换函数中的参数所需的转换序列   调用函数中相应参数的类型   宣言。隐式转换序列排名;一些   隐式转换序列比其他转换序列更好。最好的可行   函数是其参数都更好或更好的函数   等级隐式转换序列比其他所有转换序列都要多   可行的功能。编译器不允许其中的程序   编译器能够找到多个最佳的可行功能。

1,2和5都是完全匹配,因此不需要转换。

要解释3和4,请注意,如果删除double, double功能,您的程序将无法编译。这是因为3和4的模板参数cannot be deduced(因为参数类型不匹配)。因此,只有double, double函数被视为候选函数。