c/c++ 模板函数的重载
模板函数的重载
普通函数可以重载,模板函数也可以重载,但规则复杂
有下面2个函数,名字相同,返回值相同就,参数不同,符合重载。
template<typename T>
std::string moban(const T& t){}
template<typename T>
std::string moban(T* p){}
调用1
std::string s("hi");
std::cout << moban(s) << std::endl;
结果1:调用的是(const T& t),这个可以简单理解,因为参数不是指针类型,所以不适用于(T* p)。
调用2
std::string s("hi");
std::cout << moban(&s) << std::endl;
结果2:调用的是(T* p)。这个就复杂了,因为2个模板都符合,但是调用哪个呢。
- moban(const string*&) T被绑定到string*。
- moban(string*) T被绑定到string。
因为(const T& t)的实例需要进行普通指针到const指针的转换,(T* p)不需要转换,所以是更精准的匹配。
所以推导出规则1:更精准的匹配会被优先采用。
调用3
std::string s("hi");
const std::string* sp = &s;
std::cout << moban(sp) << std::endl;
结果3:调用的是(T* p)。这个就更复杂了,因为2个模板都符合,而且都是同样精准的匹配,但是调用哪个呢。
- moban(const string*&) T被绑定到string*。
- moban(string*) T被绑定到const string。
在此情况下,因为是同样精准的匹配,所以无法区分调用哪个。但是根据重载函数模板的特殊规则,调用了(T* p)。
原因是,(const T& t)本质上可以用于任何类型,包括指针类型,比(T* p)更通用,后者只能用于指针类型。
所以推导出规则2:同样精准的话,更特殊的会被优先采用。
如果非模板函数和模板函数同时存在,构成重载,会调用哪个?
有下面3个函数,名字相同,返回值相同就,参数不同,符合重载。
template<typename T>
std::string moban(const T& t){}
template<typename T>
std::string moban(T* p){}
std::string moban(const std::string& s){}
调用4
std::string s("hi");
std::cout << moban(s) << std::endl;
结果4:调用的是非模板的函数。
- (const T& t) T被绑定到string,也是可以被调用的。
但是,非模板优先模板。
所以推导出规则3:非模板和模板同时都适用的时候,非模板的会被优先采用。
调用5
std::string s("hi");
std::cout << moban(s) << std::endl;
结果5:调用的是(T* p),而没有调用非模板函数。
所以看出来,规则3有个特例,就是,如果模板的匹配比非模板的匹配更精准的时候,模板会被优先采用。
- moban(const T& t) T被绑定到char[2]。
- moban(T*) T被绑定到const char。
- moban(const std::string& s) 要求从const char*到string的类型转换。
理由:非模板也是可行的,但是需要进行一次用户定义的类型转换,因此她没有模板的匹配更精准。但是2个模板都可以被调用,但是(T*)更特例化,所以最好调用的是(T*)
所以推导出规则4:非模板和模板同时都适用的时候,非模板如果需要一次用户定义的类型转换,而模板不需要的话,模板会被优先采用。
非模板函数和模板函数的声明位置,导致结果的不同。
有下面4个函数,名字相同,返回值相同就,参数不同,符合重载。
template<typename T>
std::string moban(const T& t){}
template<typename T>
std::string moban(T* p){}
std::string moban(const char* p){
return debug_rep(std::string(p));
}
std::string moban(const std::string& s){}
调用5
std::cout << moban("hello") << std::endl;
结果5:首先调用的是(const char* p),这是没有疑问的,它是最匹配的,问题是它里面的return debug_rep(std::string(p));调用的是哪个呢?调用的是:(const T& t)。
分析:由于非模板的(const std::string& s)的定义在,(const char* p)的后面,所以return debug_rep(std::string(p));只能看到它前面的2个模板函数,所以匹配了(const T& t)。如果把(const std::string& s)的定义放在,(const char* p)的前面,return debug_rep(std::string(p));调用的就是非模板的(const std::string& s)。
c/c++ 学习互助QQ群:877684253

本人微信:xiaoshitou5854
c/c++ 模板函数的重载的更多相关文章
- 聊聊C++模板函数与非模板函数的重载
前言 函数重载在C++中是一个很重要的特性.之所以有了它才有了操作符重载.iostream.函数子.函数适配器.智能指针等非常有用的东西. 平常在实际的应用中多半要么是模板函数与模板函数重载,或者是非 ...
- [C++] 用Xcode来写C++程序[5] 函数的重载与模板
用Xcode来写C++程序[5] 函数的重载与模板 此节包括函数重载,隐式函数重载,函数模板,带参数函数模板 函数的重载 #include <iostream> using namespa ...
- [c++][语言语法]函数模板和模板函数 及参数类型的运行时判断
参考:http://blog.csdn.net/beyondhaven/article/details/4204345 参考:http://blog.csdn.net/joeblackzqq/arti ...
- C++:函数模板与模板函数
6.1 模板的概念 C++允许用同一个函数定义函数,这些函数的参数个数和参数类型不同.例如求最大值的max函数, int max(int x,int y) { return (x>y ...
- C++模板专门化与重载
最近在复习C++有关知识,又重新看<<Effective C++>>,收获颇丰.原来以前看这边书,好多地方都是浅尝辄止.<<Effective C++>> ...
- [转]C++函数模板与模板函数
1.函数模板的声明和模板函数的生成 1.1函数模板的声明 函数模板可以用来创建一个通用的函数,以支持多种不同的形参,避免重载函数的函数体重复设计.它的最大特点是把函数使用的数据类型作为参数. ...
- C++普通函数与模板函数以及特化函数重载的优先级问题
在面对C++模板的时候,需要十分注意,因为模板的复杂性有很多情况,所以最好学习模板的方法我个人认为就是用到就去学,用不到就尽量别去看各种奇门怪技,因为你就算看了,好不容易搞懂模板的实现内部了,包括元编 ...
- c++模板函数实例化的偏序机制
一:废话 今天在stackoverflow上看到一个关于c++模板specialization的问题: http://stackoverflow.com/questions/18283851/temp ...
- C++ template学习一(函数模板和模板函数)
函数模板和模板函数(1)函数模板函数模板可以用来创建一个通用的函数,以支持多种不同的形参,避免重载函数的函数体重复设计.它的最大特点是把函数使用的数据类型作为参数.函数模板的声明形式为:templat ...
随机推荐
- openlayers一:显示地图与鼠标地理坐标
openlayers两个好用的开源JS互动地图库之一,另一个是leaflet. openlayers的特点是是大而全,自身包含绝大多数功能,文档好看. leaflet是小而美,自身小,但支持扩展,好用 ...
- Takeown、Cacls、Icacls-文件、文件夹夺权用法
常用示例如下: takeown /f 文件名 获取该文件的所属权 takeown /f /r /d n 文件夹 获取整个文件夹及其下面子目录文件的所属权 takeown /f * /a /r /d ...
- LOJ #6060. 「2017 山东一轮集训 Day1 / SDWC2018 Day1」Set
有趣的思博套路题,想到了基本上加上个对线性基的理解就可以过了 首先考虑到这个把数分成两半的分别异或的过程不会改变某一位上\(1\)的总个数 因此我们求出所有数的\(\operatorname{xor} ...
- 分布式架构原理解析,Java开发必修课
1. 分布式术语 1.1. 异常 服务器宕机 内存错误.服务器停电等都会导致服务器宕机,此时节点无法正常工作,称为不可用. 服务器宕机会导致节点失去所有内存信息,因此需要将内存信息保存到持久化介质上. ...
- IM开发者的零基础通信技术入门(一):通信交换技术的百年发展史(上)
[来源申明]本文原文来自:微信公众号“鲜枣课堂”,官方网站:xzclass.com,原题为:<通信交换的百年沧桑(上)>,本文引用时已征得原作者同意.为了更好的内容呈现,即时通讯网在收录时 ...
- Activity 之使用
Activity 之使用 本文内容 1. 使用 Activity 显式简单界面 2. Activity 之间的跳转 2.1 startActivity 2.3 startActivityForResu ...
- Prometheus安装和配置node_exporter监控主机
Node_exporter是可以在* Nix和Linux系统上运行的计算机度量标准的导出器. Node_exporter 主要用于暴露 metrics 给 Prometheus,其中 metrics ...
- 数据结构之表(C语言实现)
抽象数据类型 (abstract data type,ADT) 抽象数据类型是一些操作的集合.抽象数据类型是数学中的定义,在ADT中,我们不关心操作是如何被实现的.因此,这可以看做是模块化的扩充.例如 ...
- Python爬虫实例:爬取猫眼电影——破解字体反爬
字体反爬 字体反爬也就是自定义字体反爬,通过调用自定义的字体文件来渲染网页中的文字,而网页中的文字不再是文字,而是相应的字体编码,通过复制或者简单的采集是无法采集到编码后的文字内容的. 现在貌似不少网 ...
- 解决WebMagic抓HTTPS时出现SSLException
访问我的博客 前言 在今年二月份在项目中引入了 WebMagic 技术,用来抓取合作方的书籍,详见之前文章:WebMagic之爬虫监控,这两天新接入了一个合作商,对方接口采取的是 HTTPS 协议,而 ...