C++普通函数与模板函数以及特化函数重载的优先级问题
在面对C++模板的时候,需要十分注意,因为模板的复杂性有很多情况,所以最好学习模板的方法我个人认为就是用到就去学,用不到就尽量别去看各种奇门怪技,因为你就算看了,好不容易搞懂模板的实现内部了,包括元编程啊什么的,但真正用到工作中的我相信很少,不久你也会忘掉,所以,对于模板,我们可以采取用到哪学到哪的观念去学习,这样可以节省时间并且让效率最大化。
今天主要讲在关于模板特化已经函数重载的问题,简单举下例子
1 void say(int value); 2 template <typename T>
void say(T value); 3 template<>
void say(int value);
如上三个函数,C++默认规定,如果存在非模板函数做到完全匹配(包括const和const &)就优先匹配非模板函数,然后匹配特化模板,然后匹配模板,所以上面的顺序是如果我调用say(1) 为 1 > 3 > 2 。注意,在匹配的过程中允许你的普通函数不需要做到所谓的“完全匹配”,可以有一些适当的变化比如:const或者const &,这点很关键.
在此我引用百度百科上对于重载的介绍来加深映像印象:
第一步:创建候选函数列表,其中包含有与被调函数名称相同的函数与模板函数。第三步:确定是否有最佳可行的函数。如果有,则使用。
最后,再附上一个比较容易搞混的demo
#include <iostream>
using namespace std; template<class T>
void func(T &s)
{
cout << "template version!" << endl;
cout << sizeof(s) << ":\t" << s << endl;
} void func(const char *s)
{
cout << "special version!" << endl;
cout << sizeof(s) << ":\t" << s << endl;
} int main()
{
char s[] = "asdasdasd";
func(s);
return ;
}
这个demo,调用的时候会去调用templation的版本(Windows下的cl默认是进special,我这里用的是gcc)。顺便摘录一个大牛的评论:
原因在于s对于模板函数来说是经历了一次identity conversion,其rank是Exact Match,普通函数时实参是数组类型,形参是指针类型,所以这里有array-to-pointer conversion和qualification conversions,两者的rank一样,最后的转换rank是Exact Match。然而,仅比较rank,都是一样,无区别。但是在相同情况下,identity conversion优于非indentity conversion,所以引用绑定的要优于后者.
所以我们可以试着去除const,因为没有了qualification conversions,这个时候就会优先去调用special的版本了。
参考链接: http://baike.baidu.com/view/126530.htm?fr=aladdin
http://bbs.csdn.net/topics/390577993
C++普通函数与模板函数以及特化函数重载的优先级问题的更多相关文章
- javascript模板字符串(标签函数)
前面介绍了javascript的模板字符串的基本知识,今天深入学习一下标签函数 模板字符串概述 这里先简单说一下模板字符串的概念 1.模板字符串,从名字上可以得出其实返回的是字符串,普通使用其实就想引 ...
- C++ 模板函数与模板类
一.模板函数 函数模板提供了一类函数的抽象,即代表了一类函数.当函数模板被实例化后,它会生成具体的模板函数.例如下面便是一个函数模板:
- Thinkphp模板怎么使用自定义函数
内置模板引擎支持对模板变量使用函数,并支持多个函数同时使用. 注意:自定义函数要放在项目应用目录/common/common.php中. 这里是关键. 模板变量的函数调用格式:{$varname|fu ...
- Thinkphp模板中使用自定义函数的方法
注意:自定义函数要放在项目应用目录/common/common.php中. 这里是关键. 模板变量的函数调用格式:{$varname|function1|function2=arg1,arg2,### ...
- thinkphp模板中使用自定义函数
注意:自定义函数要放在项目应用目录/common/common.php中. 这里是关键. 模板变量的函数调用格式:{$varname|function1|function2=arg1,arg2,### ...
- C++ primer(八)--内联函数 引用变量 引用传递函数参数 函数重载/模板/模板具体化
一.内联函数 常规函数和内联函数的区别在于C++编译器如何将他们组合到程序中.编译过程的最终产品是可执行程序--由一组机器语言指令组成.运行程序时,操作系统将这些指令载入到计算机内存中,因此每 ...
- c++复习基础要点02 虚函数与模板 与static inline是否共存
1. 虚函数能否定义为模板函数 当一个类有虚函数时,它一定有一个虚表,用来纪录每个虚函数的实际地址.这也就是说这个虚表的大小是在编译期就确定了的.有多少个虚函数,虚表就纪录几个. ...
- 读书笔记 effective c++ Item 46 如果想进行类型转换,在模板内部定义非成员函数
1. 问题的引入——将operator*模板化 Item 24中解释了为什么对于所有参数的隐式类型转换,只有非成员函数是合格的,并且使用了一个为Rational 类创建的operator*函数作为实例 ...
- C++模板类中友元函数的写法
首先,已声明好的类Triangle file://Triangle.h template<class T> class Triangle{ public: Triangle(T width ...
随机推荐
- Unity C# 游戏间物体间的访问
脚本语言:C# 1.在Unity工程中新建两个物体:Cube和Sphere 2.分别为Cube和Sphere添加脚本CubeScript和SphereScript: 在SphereScript这两个定 ...
- MongoDB主从配置
master的配置 # cat mongod.conf dbpath = /app/sinova/mongodata/db #指定数据库目录 logpath = /app/sin ...
- 字符串(KMP):BZOJ 3670 [Noi2014]动物园
3670: [Noi2014]动物园 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1521 Solved: 813[Submit][Status] ...
- 【贪心】CSU 1809 Parenthesis (2016湖南省第十二届大学生计算机程序设计竞赛)
题目链接: http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1809 题目大意: 给一个长度为N(N<=105)的合法括号序列.Q(Q<= ...
- 行为树(Behavior Tree)实践(1)– 基本概念
原文地址:http://www.360doc.com/content/15/0107/11/15099545_438831036.shtml 自从开博以来,每天都会关心一下博客的访问情况,看到一些朋友 ...
- [Locked] Palindrome Permutation I & II
Palindrome Permutation I Given a string, determine if a permutation of the string could form a palin ...
- Android 4.4(KitKat)中VSync信号的虚拟化
原文地址:http://blog.csdn.net/jinzhuojun/article/details/17293325 Android 4.1(Jelly Bean)引入了Vsync(Vertic ...
- 你好,C++(12)怎样管理多个类型同样性质同样的数据?3.6 数组
3.6 数组 学过前面的基本数据类型之后,我们如今能够定义单个变量来表示单个的数据.比如,我们能够用int类型定义变量来表示公交车的216路:能够用float类型定义变量来表示西红柿3.5元一斤. ...
- navigaitonBar的自定义设置
navigaitonBar的自定义设置 navigationBar介绍: navigationbar就是一个导航视图控制器上面的导航栏. 如何设置这个navigationbar? 首先我们来探讨如何来 ...
- Linux禁止ping服务
ping是一个通信协议,是ip协议的一部分,tcp/ip 协议的一部分.利用它可以检查网络是否能够连通,用好它可以很好地帮助我们分析判定网络故障.应用格式为:Ping IP地址.但服务启用ping有时 ...