template_12特化与重载

1,重载函数模板

f<int*>((int*)pi);//1
f<int>((int*)pi);//2
上面用int*替换第一个模板的T,用int来替换第二个模板的T。那么将得到两个相同参数类型(int*)的同名函数。
也就是不仅同名模板可以同时存在,它们各自具有相同参数类型和返回类型的实例化体也可以同时存在。

f(pi);对于这两个模板实参演绎都可以获得成功,即f<int*>(int*)和f<int>(int*).这也就意味着调用是二义性的。
但是,考虑重载解析的额外规则:选择"产生自更特殊的模板的函数"。因此选择了第二个模板。
当然如果要在两个特殊程度相同的模板中选择,将不能做出决定这是产生二义性。

模板函数也可以和非模板函数同事重载,会优先选择非模板函数。

2,签名

3,显式特化
类模板不能被重载,但可以使用另一种替换的机制来实现这种透明自定义模板功能,这就是显式特化,也称之为全局特化。
它为模板提供了一种使模板参数可以被全局替换的实现。
事实上类模版和函数模板都可以被全局替换,而且类模版的成员(成员函数,嵌入类,静态成员变量等)都能被全局替换。
全局特化和局部特化都没有引入一个全新的模板或模板实例,它们只是对原来的泛型(或非特化)模板中已经隐式声明的实例提供另一种定义。

template<> class S<特化的模板实参>

全局特化的实现并不需要与泛型实现有任何关联,可以包含不同名称的成员函数。全局特化只是和类模板的名称有关联。

4,全局类模板特化


对于特化的声明,因为它不是模板声明,所以应该使用(位于类外部)普通成员定义语法来定义全局类模板特化的成员,也就是不能指定template<>前缀。


全局模板特化和由模板生成的实例化版本不能共存于同一个程序中。


实例化置于全局模板特化位置之后,并且定义了全部模板特化,此时这个实例化其实是走的全局模板特化所以OK.

如果全局模板特化的编译单元与跟实例化或泛型声明的编译单元不在同一个编译单元,容易出现很难捕捉的错误。
我们需要确认特化的声明对泛型模板的所以用户都是可见的。
特化声明通常都应该位于模板声明之后。
然而泛型实现也可能来自外部资源包,我们可以创建一个包含泛型声明的头文件并让特化什么位于其后。
通常都应该避免让模板特化来自外部资源包。

5,全局函数模板特化
全局函数模板特化和类模板特化大体上是一致的,唯一区别是:函数模板特化引入了重载和实参演绎这两个概念。

全局特化声明的声明对象并不是一个模板,因此对于非内联的全局函数模板特化的声明而言,在同个程序中它的定义只能很粗线一次。
全局函数模板特化的声明必须紧跟在模板定义的后面,以避免使用一个模板直接生成的函数。

特化声明禁止模板进行实例化;
为了避免出现重复定义错误,就不能把定义放在头文件里。解决方案是把这个特化声明为内联函数,此时该函数的定义就可以放在头文件中。

6,全局成员特化

7,局部类模板特化

时间: 2024-11-10 10:55:51

template_12特化与重载的相关文章

特化与重载

现在我们已经知道如何使一个泛型定义扩展成一些相关的类家族和函数家族.但是有些时候,我们需要同一个名字的函数的不同实现(透明定义),为的是在不同情况下获得较高的性能,在这种情况下就不是简单的参数替换就能够解决的. 一.透明定义使用的技术 对于函数模板使用的透明定义的技术是:函数模板的重载 对于类模板的使用透明定义的技术是:类模板的特化(全局特化和局部特化) 二.重载函数模板 两个名称相同的模板可以同时存在,还可以对他们进行实例化. template<typename T> int f(T) {

C++普通函数与模板函数以及特化函数重载的优先级问题

在面对C++模板的时候,需要十分注意,因为模板的复杂性有很多情况,所以最好学习模板的方法我个人认为就是用到就去学,用不到就尽量别去看各种奇门怪技,因为你就算看了,好不容易搞懂模板的实现内部了,包括元编程啊什么的,但真正用到工作中的我相信很少,不久你也会忘掉,所以,对于模板,我们可以采取用到哪学到哪的观念去学习,这样可以节省时间并且让效率最大化. 今天主要讲在关于模板特化已经函数重载的问题,简单举下例子 1 void say(int value); 2 template <typename T>

函数模板示例(三) 模板函数的特化与重载

function3.h中的代码: #ifndef FUNCTION3_H #define FUNCTION3_H #include <string> #include <cstring> #include <iostream> template <typename T> T myMax(const T p1, const T p2) { std::cout << "template default func" <<

C++ 模板编程 - 第十二章 特化与重载

对程序效率的考虑 template<typename T> inline void swap(T *a, T * b) { T tmp(*a); *a = *b; *b = tmp; } 上面的代码实际上进行了三次拷贝,如果类型的尺寸比较大,显然会很浪费时间.解决方案是可以给特定的类型定义更高效的用于交换的成员函数——其实这不是重点,重点是我之前从来没有考虑过这个问题!

C++—模板(2)类模板与其特化

我们以顺序表为例来说明,普通顺序表的定义如下: 1 typedef int DataType; 2 //typedef char DataType; 3 class SeqList 4 { 5 private : 6 DataType* _data ; 7 int _size ; 8 int _capacity ; 9 } ; 模板类也是模板, 必须以 关键字templ ate开头, 后接模板形参表. 模板类一般格式如下:template<class 形参名 1, class 形参名 2, .

C++ template —— 模板特化(五)

本篇讲解模板特化------------------------------------------------------------------------------------------------------------第12章 特化和重载------------------------------------------------------------------------------------------------------------前面几篇博客讲解了C++模板如何

为什么不要特化函数模版?

/* Style Definitions */ table.MsoNormalTable {mso-style-name:普通表格; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-priority:99; mso-style-parent:""; mso-padding-alt:0cm 5.4pt 0cm 5.4pt; mso-para-margin:0cm;

C++ 模板应用浅析

把曾经写的C++模板的应用心得发表出来. 回忆起当时在学习C++模板时的无助和恐惧,如今还心有余悸.我分享出来我的心得,仅仅希望别人少走弯路,事实上它就这么几种使用方法,不须要害怕. 我总结了模板的四种使用方式,基本覆盖了大部分的模板使用场景,了解了这四种方式.就能够在看其他代码时理解别人为什么会在这个地方用模板. 模板的四大场景 1.数据类型与算法相分离的泛型编程 2.类型适配Traits 3.函数转发 4.元编程 1.数据类型与算法相分离的泛型编程 在模板编程中,最常见的就是此类使用方法.将

Effective C++ 条款25 考虑写出一个不抛出异常的swap函数

1. swap是STL的一部分,后来成为异常安全性编程(exception-safe programming)(见条款29)的一个重要脊柱,标准库的swap函数模板定义类似以下: namespace std{ template<typename T> swap(T& lhs,T& rhs){ T temp(lhs); lhs=rhs; rhs=temp; } } 只要T类型支持拷贝构造以及拷贝赋值,标准库swap函数就会调用T的拷贝构造函数和拷贝构造操作符完成值的转换,但对于某