【问题标题】:How are templates, and specialised templates模板和专用模板如何
【发布时间】:2012-10-23 19:52:34
【问题描述】:

这是我不理解的代码

#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)
}

calc 有 5 个函数调用,所以我将它们称为 1) - 5),具体取决于它们的位置。

1) 有点道理。 0 是整数,ival 是整数,调用 calc(T, T) 是有意义的。尽管如此,我觉得我对此的推理是错误的。毕竟,它们都是双精度数,所以如果调用 calc(double, double),那也是有意义的。所以在这里寻求澄清。

2) 没有戏剧,都是双打,调用 calc(double, double)。很简单。

3) fd 是一个浮点数。可以调用 calc(T, T) 或 calc(double, double)。因为 1) 导致了对 calc(T, T) 的调用,所以我假设这里也是如此,因为我们再次有一个参数为 0,但是,这调用了 calc(double, double)。所以这让我很困惑,特别是 this 和 1) 之间的区别

4) 我的第一个想法是 0 是有效字符,'J' 也是如此,所以它调用 calc(char, char)。它可能会使用常见的整数类型调用 calc(T, T)。但是不,两者都错了,它调用 calc(double, double)。我对这个很困惑。对我来说毫无意义。

5) 是有道理的,但前提是我应用与 4) 相同的逻辑,这在 4) 中是错误的,所以如果我要看到另一个使用模板的示例,我将不确定是什么逻辑申请。

所以寻找解释为什么这个程序会这样做。

谢谢。

【问题讨论】:

  • 在静态绑定中,编译器更喜欢普通的重载规则而不是模板特化:只有当它无法确定手头的参数可以接受的重载时,它才会求助于后者。不过,我不能引用标准的相关部分。
  • 如果函数模板参数不匹配完全(即需要隐式类型转换),则模板不被视为候选。
  • @n.m.:但即使在这种情况下,编译器也更喜欢重载,即使它需要一些转换才能调用它,对吧?
  • 您还应该问的问题是,如果 calc(double,double) 根本不在图片中,其中有多少会编译,我的意思是专门针对第四个。试试看。

标签: c++ template-specialization


【解决方案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)完全匹配

【讨论】:

    【解决方案2】:

    我建议你阅读overload resolution:

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

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

    创建一组候选函数后,编译器创建一个 一组可行的功能。这组函数是 候选函数。每个可行函数的参数个数 与您用来调用 f() 的参数数量一致。

    编译器选择最佳可行函数,函数 调用时 C++ 运行时环境将使用的声明 f(),来自一组可行的函数。编译器通过 隐式转换序列。隐式转换序列是 转换函数中的参数所需的转换序列 调用函数中对应参数的类型 宣言。对隐式转换序列进行排序;一些 隐式转换序列比其他序列更好。最佳可行 函数是其参数都具有更好或 与其他所有隐式转换序列同等排名的隐式转换序列 可行的功能。编译器将不允许在其中的程序 编译器能够找到不止一个最佳可行函数。

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-13
      相关资源
      最近更新 更多