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 模板和泛型编程)实例化

C++ Primer 5th笔记(chap 16 模板和泛型编程)可变参数模板

C++ Primer 5th笔记(chap 16 模板和泛型编程)模板实参