C++primer阅读笔记-模板与泛型编程(重载与模板)
2015-09-07 11:10
453 查看
函数模板可以被另一个模板或者一个非模板函数重载,名字相同的函数必须具有不同数量或类型的参数。
设计到函数模板,函数匹配规则满足:
对于一个调用,其候选函数包括所有模板实参推断成功的函数模板实例
候选函数总是可行的,因为模板实参推断会排出任何不可行的模板
可行函数按照类型转换来排序
如果恰有一个函数提供比其他函数都更好的匹配,则选择此函数,如果有多个函数提供同样好的匹配,则:
如果同样好的函数中只有一个非模板函数,则选择此函数
如果没有非模板函数,有多个函数模板,则选择其中一个比其他模板更特例化的模板
否则此调用有歧义
下面是打印指针的debug_rep版本
只有第一个版本的debug_rep是可行的,第二版本要求一个指针参数
第一版本能生成实例,其T的类型是string *,需要进行普通指针到const指针的转换
第二版本T类型为string,此为更精确匹配
两个版本都是可行的,都是精确匹配
第一个版本实例为:
第二个版本实例为:
由于第二版本比第一版本更加特例化,固解析为第二版本。
考虑下边代码
第一和第三个版本都能提供同样好的匹配
第一版本实例化为
存在同样好的模板和非模板函数时,编译器会选择非模板函数,当存在多个同样好的非模板函数时,编译器会选择最特例化的版本,一个非模板函数比模板函数更加特例化
上述三个版本都可行
debug_rep(const T&),T为char[6]
debug_rep(T*),T为const char*
debug_rep(const string&),要求从const char*到string的类型转换
对给定的实参来说,第二个版本需要一次数组到指针的转换,这是精确匹配
非模板版本需要一次用户定义的类ixngzhuanhuan,因此没有精确匹配那么好
对于重载函数模板的函数,如果编译器可以从模板实例化出与调用匹配的版本,则缺少的声明就不重要了
设计到函数模板,函数匹配规则满足:
对于一个调用,其候选函数包括所有模板实参推断成功的函数模板实例
候选函数总是可行的,因为模板实参推断会排出任何不可行的模板
可行函数按照类型转换来排序
如果恰有一个函数提供比其他函数都更好的匹配,则选择此函数,如果有多个函数提供同样好的匹配,则:
如果同样好的函数中只有一个非模板函数,则选择此函数
如果没有非模板函数,有多个函数模板,则选择其中一个比其他模板更特例化的模板
否则此调用有歧义
编写重载模板
下面函数可以生成一个对象对应的string表示,该对象是任何具备输出运算符的类型//打印任何我们不能处理的类型 template<tyename T>string debug_rep(const T &t) { ostringstream ret; ret << t; return ret.str();//返回ret绑定的string副本 }
下面是打印指针的debug_rep版本
//打印任何我们不能处理的类型 template<tyename T>string debug_rep(const T *t) { ostringstream ret; ret << t; if(t) ret << "pointer:" << p; else ret << "null pointer"; return ret.str();//返回ret绑定的string副本 }
string s("hello"); debug_rep(s);//调用第一个版本的debug_rep
只有第一个版本的debug_rep是可行的,第二版本要求一个指针参数
debug_rep(&s);//调用第二版本的debug_rep
第一版本能生成实例,其T的类型是string *,需要进行普通指针到const指针的转换
第二版本T类型为string,此为更精确匹配
多个可行版本
考虑一下代码:const string *sp = &s; cout << debug_rep(sp) <<endl;
两个版本都是可行的,都是精确匹配
第一个版本实例为:
debug_rep<string&>(const string *&),T被绑定为string*
第二个版本实例为:
debug_rep<const string>(const string *),T被绑定为const string
由于第二版本比第一版本更加特例化,固解析为第二版本。
非模板和模板重载
string debug_rep(const string &s) { return'"'+s+'"'; }
考虑下边代码
string s("hello"); debug_rep(s);//调用第三个非模块版本的debug_rep
第一和第三个版本都能提供同样好的匹配
第一版本实例化为
debug_rep<string>(const string &),T被绑定到string
存在同样好的模板和非模板函数时,编译器会选择非模板函数,当存在多个同样好的非模板函数时,编译器会选择最特例化的版本,一个非模板函数比模板函数更加特例化
重载与类型转换
考虑下边代码cout << debug_rep("hello");//调用第二版本
上述三个版本都可行
debug_rep(const T&),T为char[6]
debug_rep(T*),T为const char*
debug_rep(const string&),要求从const char*到string的类型转换
对给定的实参来说,第二个版本需要一次数组到指针的转换,这是精确匹配
非模板版本需要一次用户定义的类ixngzhuanhuan,因此没有精确匹配那么好
缺少生命可能导致程序行为异常
使用一个忘记声明的函数,代码将会编译失败对于重载函数模板的函数,如果编译器可以从模板实例化出与调用匹配的版本,则缺少的声明就不重要了
相关文章推荐
- C++Primer笔记之关联容器的使用详解
- 如何更好的利用《C++ Primer》学习C++?
- C++primer 第十章 单词转换程序 运行不了解决办法
- 头文件中包含const与非const对象
- 几个标准库类型的简单使用
- C++Primer _vector _习题3.13
- C++Primer _vector _习题3.14
- Sales_item.h (C++ Primer 第五版)
- forward_list未定义+=符号,而改用advance()函数改变迭代器
- C++ primer 笔记
- C++Primer学习笔记
- 重读c++primer (第五版) -- 引子
- (福利)”C++Primer笔记“和”Java经典入门笔记“
- C++复习学习提纲
- [C++ Primer]第一章 快速入门
- C++primer阅读笔记-模板与泛型编程(模板实参推断)
- C++primer阅读笔记-重载运算与类型转换(可调用对象与function)
- C++primer 阅读笔记-模板与泛型编程(成员模板)
- C++Primer(第十一章课后习题程序题源代码)
- C++Primer(第10章课后程序题源代码)