C++ Primer 5th笔记(chap 16 模板和泛型编程)重载与模板
Posted thefist11
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++ Primer 5th笔记(chap 16 模板和泛型编程)重载与模板相关的知识,希望对你有一定的参考价值。
1. 定义
函数模板可以被另一个模板或一个普通非模板函数重载: 名字相同的函数必须具有不同数量或类型的参数
1.1 函数模板匹配因素
- 对于一个调用, 其候选函数包括所有模板实参推断成功的函数模板实例。
- 候选的函数模板总是可行的, 因为模板实参推断会排除任何不可行的模板。
- 可行函数( 模板与非模板) 按类型转换( 如果对此调用需要的话) 来排序。 当然, 可以用于函数模板调用的类型转换是非常有限的
- 如果恰有一个函数提供比任何其他函数都更好的匹配, 则选择此函数。
但是, 如果有多个函数提供同样好的匹配, 则:
. 如果同样好的函数中只有一个是非模板函数, 则选择此函数。
. 如果同样好的函数中没有非模板函数, 而有多个函数模板, 且其中一个模板比其他模板更特例化, 则选择此模板。
. 否则, 此调用有歧义
2. 举例
//打印任何我们不能处理的类型
template <typename T> string debug_rep (const T &t )
{
ostringstream ret;
ret « t; //使用T的输出运算符打印t的一个表示形式
return ret.str( ); //返回ret绑定的string的一个副本
}
//打印指针的值, 后跟指针指向的对象
//注意: 此函数不能用于 char*;
template ctypename T> string debug_rep (T *p)
{
ostringstream ret;
ret « "pointer: " « p;
if (p)
ret « " "« debug_rep (*p); //打印指针本身p指向的值
else
ret « null pointer"; //p 为空
return ret.str ( ); //返回 ret 绑定的 string的一个副本
}
2.1
string s ("hi");
cout « debug_rep (s) << endl;//第一个版本
2.2
cout << debug_rep ( &s) « endl;
两个函数都生成可行的实例:
- debug_rep (const string* & ) , 由第一个版本的 debug_rep 实例化而来, T被绑定到 string*。
- debug_rep (string* ) , 由第二个版本的 debug_rep 实例化而来, T 被绑定到string。
选择第二个版本,第一个版本的实例需要进行普通指针到 const 指针的转换。
2.3 当有多个重载模板对一个调用提供同样好的匹配时, 应选择最特例化的版本
const string *sp;
cout « debug_rep (sp) « endl;
此例中的两个模板都是可行的, 而且两个都是精确匹配:
• debug_rep (const string* & ) , T被绑定到 string*。
• debug_rep (const string* ) , T被绑定到 const string。
在此情况下, 正常函数匹配规则无法区分这两个函数。 我们可能觉得这个调用将是有歧义的。 但是, 根据重载函数模板的特殊规则, 此调用被解析为 debug_rep ( T* ) , 即更特例化的版本。
模板 debug_rep (const T &) > 本质上可以用于任何类型, 包括指针类型,比 debug_rep ( T*)更通用, 后者只能用于指针类型。
以上是关于C++ Primer 5th笔记(chap 16 模板和泛型编程)重载与模板的主要内容,如果未能解决你的问题,请参考以下文章
C++ Primer 5th笔记(chap 16 模板和泛型编程)std::move
C++ Primer 5th笔记(chap 16 模板和泛型编程)模板特例化
C++ Primer 5th笔记(chap 16 模板和泛型编程)类模板特例化
C++ Primer 5th笔记(chap 16 模板和泛型编程)实例化