现在的位置: 首页 > 综合 > 正文

调用的是模板函数还是重载函数?

2013年10月09日 ⁄ 综合 ⁄ 共 1635字 ⁄ 字号 评论关闭
  1. // MaxTemplate.cpp : Defines the entry point for the console application.
  2. //
  3. #include "stdafx.h"
  4. #include <iostream>
  5. #include <string>
  6. using namespace std;
  7. inline int const& max (int const& a, int const& b)
  8. {
  9.     return a < b ? b : a;
  10. }
  11. // 传回两任意类型的数值中的较大者
  12. template <typename T>
  13. inline T const& max(T const& a, T const& b)
  14. {
  15.     return a > b ? a : b; 
  16. }
  17. // 传回三个任意类型值中的最大者
  18. template <typename T>
  19. inline T const& max (T const& a, T const& b, T const& c)
  20. {
  21.     return ::max (::max(a,b), c);
  22. }
  23. int main()
  24. {
  25.     ::max(7, 42, 68);       // 调用「接受三个自变量」的函数
  26.     ::max(7.0, 42.0);       // 调用 max<double>(经由自变量推导)
  27.     ::max('a''b');        // 调用 max<char>(经由自变量推导)
  28.     ::max(7, 42);           // 调用「接受两个 int 自变量」的 non-template 函数
  29.     ::max<>(7, 42);         // 调用 max<int>(经由自变量推导)
  30.     ::max<double>(7, 42);   // 调用 max<double>(无需自变量推导)
  31.     ::max('a', 42.7);       // 调用「接受两个 int 自变量」的 non-template 函数
  32. }

/* 译注:ICL7.1/g++ 3.2 顺利通过本例。VC6 无法把最后一个调用匹配到常规的(non-template)函数
max(),造成编译失败。VC7.1 可顺利编译,但对倒数第二个调用给出警告:虽然它调用的是 function template
max(),但它发现常规函数 max()与这个调用更匹配。*/
这个例子说明:non-template function 可以和同名的 function template 共存,也可以和其相同类型
的具现体共存。当其它要素都相等时,重载解析机制会优先选择 non-template function,而不选
择由 function template 实例化后的函数实体。上述第四个调用便是遵守这条规则:
::max(7, 42); // 两个自变量都是 int,吻合对应的 non-template function
但是如果可由 template 产生更佳匹配,则 template 具现体会被编译器选中。前述的第二和第
三 个调用说明了这一点:
::max(7.0, 42.0); // 调用 max<double>(经由自变量推导)
::max('a', 'b'); // 调用 max<char>(经由自变量推导)
调用端也可以使用空的 template argument list,这种形式告诉编译器「只从 template 具现体中挑
选适当的调用对象」,所有template parameters 都自call parameters 推导而得:
::max<>(7, 42); // 调用 max<int>(经由自变量推导)
另外,「自动类型转换」只适用于常规函数,在templates 中不予考虑,因此前述最后一个调用调
用的是 non-template 函数。在该处,'a' 和 42.7 都被转型为 int:
::max('a', 42.7); // 本例中只有 non-template 函数才可以接受两个不同类型的自变量

抱歉!评论已关闭.