模板的特化(具体化)

重点注意

1)类模板和函数模板都可以被全特化;

2)类模板能偏特化,不能被重载;

3)函数模板可以实现重载,不能被偏特化;

4)类模板调用优先级:全特化类>偏特化类>主版本模板类;

6)函数模板同时存在具体化模板、函数模板重载、和常规函数重载时候,调用优先级:

常规函数 > 具体化模板函数 > 常规模板函数;《这不是比较顺序,而是优先级》

注意:重载决议时,优先决议出是不是符合常规函数,不存在符合的普通函数,才会再决议出符合的函数主模板,对于函数模板重载决议,会无视特化存在(标准规定:重载决议无视模板特化,重载决议发生在主模板之间),决议出函数主模板后,如果函数主模板存在符合的具体化函数模板,才会调用具体化函数模板;

7)不能将函数模板特化和重载混为一谈
函数特化都没有引入一个全新的模板或者模板实例,它们只是对原来的主(或者非特化)模板中已经隐式声明的实例提供另一种定义。在概念上,这是一个相对比较重要的现象,也是特化区别于重载模板的关键之处。

如果使用普通重载函数,那么不管是否发生实际的函数调用,都会在目标文件中生成该函数的二进制代码。而如果使用函数模板特化版本,除非发生函数调用,否则不会在目标文件中包含特化模板函数的二进制代码。这符合函数模板的“惰性实例化”准则。

8>特化可以改变函数体

函数模板

1)常规函数

// 常规函数
void Compare(const char* first, const char* second)
{cout << "const char* ordinary function " << endl;if (strcmp(first, second) > 0) // 比较char*,需要区别函数主模板进行处理{cout << "first:" << first << " > second:" << second << endl;}else{cout << "first:" << first << " <= second:" << second << endl;}
}

2)函数主模板a

//函数主模板
template<typename T, typename N> void Compare(T first, N second)
{cout << "Standard function template <T, N>" << endl;if (first < second){cout << "first < second" << endl;}else{cout << "first >= second" << endl;}
}

3)函数模本b–全特化

//针对char*类型的比较函数,不能直接使用大于号或小于号比较元素,需要特化;
//函数模板-全特化
template<> void Compare(const char* first, const char* second)
{cout << "const char* specialization <const char*, const char*>" << endl;if (strcmp(first, second) > 0) // 比较char*,需要区别函数主模板进行处理{cout << "first:" << first << " > second:" << second << endl;}else{cout << "first:" << first << " <= second:" << second << endl;}
}

4)函数模板c-重载,作为一个独立的函数主模板

//函数模板-重载,不是偏特化,它会作为一个独立的函数主模板
template<typename T, typename N> void Compare(T* first, N* second)
{cout << "function template overload <T*, N*>" << endl;cout << "T type: " << typeid(T).name() << ", N type : " << typeid(N).name() << endl;if (strcmp(typeid(T).name(), "char") == 0 && strcmp(typeid(N).name(), "char") == 0){if (strcmp(first, second) > 0) // 比较char*,需要区别函数主模板进行处理{cout << "first:" << first << " > second:" << second << endl;}else{cout << "first:" << first << " <= second:" << second << endl;}}else{if (*first < *second){cout << "first < second" << endl;}else{cout << "first >= second" << endl;}}
}

5)函数模板之间的重载决议

【1】当代码中存在如下顺序的申明时,template<typename T, typename N> void Compare(T first, N second) //函数主模板a{.....}template<> void Compare(const char* first, const char* second) // 函数主模板a的全特化模板 b{.....}template<typename T, typename N> void Compare(T* first, N* second) // 函数主模板c,是函数主模板a的重载{.....}那么,发生如下函数调用时,Compare("1", "2");
函数将调用函数主模板c因为在调用Compare("1", "2")时,先会进行重载决议,
发生重载决议,会无视特化存在(标准规定:重载决议无视模板特化,重载决议发生在主模板之间),
那么就会决议出函数主模板c;
那将会调用函数主模板c《根据第六条,:重载决议时,优先决议出是不是符合常规函数,不存在符合的普通函数,才会再决议出符合的函数主模板,对于函数模板重载决议,会无视特化存在(标准规定:重载决议无视模板特化,重载决议发生在主模板之间),决议出函数主模板后,如果函数主模板存在符合的具体化函数模板,才会调用具体化函数模板;》

6)常规函数与函数模板之间的重载决议

当代码中存在如下顺序的申明时,template<typename T, typename N> void Compare(T first, N second) //函数主模板a{.....}template<> void Compare(const char* first, const char* second) // 函数主模板a的全特化模板 b{.....}template<typename T, typename N> void Compare(T* first, N* second) // 函数主模板c,是函数主模板a的重载{.....}
void Compare(const char* first, const char* second) // 常规函数{.....}那么,发生如下函数调用时,Compare("1", "2");函数将调用常规函数因为在调用Compare("1", "2")时,先会进行重载决议,重载决议会优先决议是否存在符合条件的常规函数。

7)函数模板全部实现


#include<iostream>
using namespace std;
#include<string.h>
#include<vector>/******************************* template function start ****************************************///函数主模板
template<typename T, typename N> void Compare(T first, N second)
{cout << "Standard function template <T, N>" << endl;if (first < second){cout << "first < second" << endl;}else{cout << "first >= second" << endl;}cout << endl;
}//函数模板-全特化
template<> void Compare(const char* first, const char* second)
{cout << "const char* specialization <const char*, const char*>" << endl;if (strcmp(first, second) > 0) // 比较char*,需要区别函数主模板进行处理{cout << "first:" << first << " > second:" << second << endl;}else{cout << "first:" << first << " <= second:" << second << endl;}cout << endl;
}//函数主模板-重载,不是偏特化,它会作为一个独立的函数主模板
template<typename N> void Compare(int first, N second)
{cout << "partitial specialization <int, N>" << endl;if (first < second){cout << "first < second" << endl;}else{cout << "first >= second" << endl;}cout << endl;
}//函数模板-重载,不是偏特化,它会作为一个独立的函数主模板
template<typename T, typename N> void Compare(T* first, N* second)
{cout << "function template overload <T*, N*>" << endl;cout << "T type: " << typeid(T).name() << ", N type : " << typeid(N).name() << endl;if (strcmp(typeid(T).name(), "char") == 0 && strcmp(typeid(N).name(), "char") == 0){if (strcmp(first, second) > 0) // 比较char*,需要区别函数主模板进行处理{cout << "first:" << first << " > second:" << second << endl;}else{cout << "first:" << first << " <= second:" << second << endl;}}else{if (*first < *second){cout << "first < second" << endl;}else{cout << "first >= second" << endl;}}cout << endl;
}//函数主模板-重载,不是偏特化,它会作为一个独立的函数主模板
template<typename T, typename N> void Compare(std::vector<T>& first, std::vector<N>& second)
{cout << "to vector partitial specialization <std::vector,std::vector>" << endl;if (first.size() < second.size()){cout << "first.size() < second.size()" << endl;}else{cout << "first.size() >= second.size()" << endl;}cout << endl;
}// 常规函数
void Compare(const char* first, const char* second)
{cout << "const char* ordinary function " << endl;if (strcmp(first, second) > 0) // 比较char*,需要区别函数主模板进行处理{cout << "first:" << first << " > second:" << second << endl;}else{cout << "first:" << first << " <= second:" << second << endl;}cout << endl;
}// 测试函数模板功能
void Test_Temmplate_Function()
{cout << __FUNCTION__ << ":" << endl;Compare(1,2);Compare(1, 2.0);Compare(1.0, 2.0);Compare('1', '2');Compare("1", "2");vector<int> v1 = { 1 };vector<int> v2 = { 2 };Compare(v1, v2);cout << endl;
}/******************************* template function end ****************************************/int main()
{Test_Temmplate_Function();
}

//输出结果

Test_Temmplate_Function:
partitial specialization <int, N>
first < secondpartitial specialization <int, N>
first < secondStandard function template <T, N>
first < secondStandard function template <T, N>
first < secondconst char* ordinary function
first:1 <= second:2to vector partitial specialization <std::vector,std::vector>
first.size() >= second.size()

5.类模板

必须先有泛化版本类模板(主模板),才有特化版本类模板。

1)类模板特化分类

特化为绝对类型(全特化);

特化为引用,指针类型(半特化、偏特化);

特化为另外一个类模板(复杂点的偏特化)

2)类模板-主模板类

//类模板-主版本模板类
template<typename T, typename N> class MyClass
{public:void Compare(T first, N second){cout << "standard function template" << endl;cout << __FUNCTION__ << ":" << endl;if (first < second){cout << "first < second" << endl;}else{cout << "first >= second" << endl;}}
};

3)类模板-全特化(具体化)

//类模板-全特化(具体化)
template<> class MyClass<const char*, const char*>
{public:void Compare(const char* first, const char* second){cout << "const char* specialization" << endl;cout << __FUNCTION__ << ":" << endl;if (strcmp(first, second) > 0) // 比较char*,需要区别函数主模板进行处理{cout << "first:" << first << " > second:" << second << endl;}else{cout << "first:" << first << " <= second:" << second << endl;}}
};

4)类模板-特化(部分具体化),对部分模板参数进行特化为一般类型

//类模板-特化(部分具体化),对部分模板参数进行特化
template<typename N> class MyClass<int, N>
{public:void Compare(int first, N second){cout << "partitial specialization" << endl;cout << __FUNCTION__ << ":" << endl;if (first < second){cout << "first < second" << endl;}else{cout << "first >= second" << endl;}}
};

5)类模板-特化(部分具体化),将模板参数特化为指针

//类模板-特化(部分具体化),将模板参数特化为指针
template<typename T, typename N> class MyClass<T*, N*>
{public:void Compare(T* first, N* second){cout << "ptr partitial specialization" << endl;cout << __FUNCTION__ << ":" << endl;if (first < second){cout << "first < second" << endl;}else{cout << "first >= second" << endl;}}
};

6)类模板-特化(部分具体化),将模板参数特化为另一个模板类

//类模板-特化(部分具体化),将模板参数特化为另一个模板类
template<typename T, typename N> class MyClass<vector<T>, vector<N>>
{public:void Compare(const vector<T>& first, const vector<N>& second){cout << "to vector partitial specialization" << endl;cout << __FUNCTION__ << ":" << endl;if (first.size() < second.size()){cout << "first.size < second.size" << endl;}else{cout << "first.size >= second.size" << endl;}}
};

7)类模板特化全部实现


/******************************* template class start ****************************************///类模板-主版本模板类
template<typename T, typename N> class MyClass
{public:void Compare(T first, N second){cout << "standard function template" << endl;cout << __FUNCTION__ << ":" << endl;if (first < second){cout << "first < second" << endl;}else{cout << "first >= second" << endl;}}
};//类模板-全特化(具体化)
template<> class MyClass<const char*, const char*>
{public:void Compare(const char* first, const char* second){cout << "const char* specialization" << endl;cout << __FUNCTION__ << ":" << endl;if (strcmp(first, second) > 0) // 比较char*,需要区别函数主模板进行处理{cout << "first:" << first << " > second:" << second << endl;}else{cout << "first:" << first << " <= second:" << second << endl;}}
};//类模板-特化(部分具体化),对部分模板参数进行特化
template<typename N> class MyClass<int, N>
{public:void Compare(int first, N second){cout << "partitial specialization" << endl;cout << __FUNCTION__ << ":" << endl;if (first < second){cout << "first < second" << endl;}else{cout << "first >= second" << endl;}}
};//类模板-特化(部分具体化),将模板参数特化为指针
template<typename T, typename N> class MyClass<T*, N*>
{public:void Compare(T* first, N* second){cout << "ptr partitial specialization" << endl;cout << __FUNCTION__ << ":" << endl;if (first < second){cout << "first < second" << endl;}else{cout << "first >= second" << endl;}}
};//类模板-特化(部分具体化),将模板参数特化为另一个模板类
template<typename T, typename N> class MyClass<vector<T>, vector<N>>
{public:void Compare(const vector<T>& first, const vector<N>& second){cout << "to vector partitial specialization" << endl;cout << __FUNCTION__ << ":" << endl;if (first.size() < second.size()){cout << "first.size < second.size" << endl;}else{cout << "first.size >= second.size" << endl;}}
};// 测试类模板功能
void Test_Temmplate_Class()
{cout << __FUNCTION__ << ":" << endl;MyClass<char, int> c_i_myclass;c_i_myclass.Compare(1, 2);printf("function address: %p\n\n", &MyClass<char,int>::Compare);MyClass<int, double> i_d_myclass;i_d_myclass.Compare(1, 2);printf("function address: %p\n\n", &MyClass<int, double>::Compare);MyClass<int, int> i_i_myclass1;i_i_myclass1.Compare(1, 2);printf("function address: %p\n\n", &MyClass<int, int>::Compare);MyClass<int, int> i_i_myclass2;i_i_myclass2.Compare(1, 2);printf("function address: %p\n\n", &MyClass<int, int>::Compare);MyClass<const char*, const char*> c_c_c_c_myclass;c_c_c_c_myclass.Compare("1", "2");printf("function address: %p\n\n", &MyClass<const char*, const char*>::Compare);MyClass<vector<int>, vector<char>> vc_i_vc_c_maclass;vc_i_vc_c_maclass.Compare({ 1 }, { 1,2 });printf("function address: %p\n\n", &MyClass<vector<int>, vector<char>>::Compare);cout << endl;
}/******************************* template class end ****************************************/

运行结果

Test_Temmplate_Class:
standard function template
Compare:
first < second
function address: 0x5581ffb2399cpartitial specialization
Compare:
first < second
function address: 0x5581ffb23a84partitial specialization
Compare:
first < second
function address: 0x5581ffb23b76partitial specialization
Compare:
first < second
function address: 0x5581ffb23b76const char* specialization
Compare:
first:1 <= second:2
function address: 0x5581ffb23834to vector partitial specialization
Compare:
first.size < second.size
function address: 0x5581ffb23e8e

此外,特化的模板只在传入特定的参数时才会调用,否则调用主模板


//模板操作自定义类型:方法一采用重载函数,将<<重载为友元函数,能访问保护成员。也能打印对象
#include <iostream>
#include<string.h>
using namespace std;
template<class T>
void print(T object)
{cout<<object<<endl;cout<<" choose_this "<<endl;
}
class point
{friend  void print<point>(point object);
protected:int x;int y;string name;
//改正方法public:point(int x, int y,string name):x(x),y(y),name(name){};};
template<>
void print<point>(point object)
{cout<<object.x<<" "<<object.y<<" "<<object.name<<endl;cout<<" choose_that "<<endl;}
int main()
{  print(255);cout<<"*****************************"<<endl;point pp(11,22,"x and y");//隐式调用print (pp);
}

调用结果

255choose_this
*****************************
11 22 x and ychoose_that

特化的模板只有特定的参数才能被调用,否则不会

模板的特化(具体化)相关推荐

  1. C++之函数模板、类模板、模板的特化

    目录 1.什么是模板? 2.类模板的定义如下: 3.模板分类? 1.模板参数有两种: 2.模板的类型 1.函数模板 2.类模板 4.模板实例化 5.模板实现链栈 1.C语言版 2.C++版本 1.什么 ...

  2. Th4.6:模板全特化、偏特化(局部特化)详述

    本小节回顾的知识点分别是模板全特化.偏特化(局部特化). 今天总结的知识分为以下4个大点: (1)特化与泛化 (2)类模板特化     (2.1)类模板全特化         a)常规全特化      ...

  3. C++_模板特化(specialization),模板偏特化(局部特化)(partial specialization)

    C++_模板特化(specialization),模板偏特化(局部特化)(partial specialization) 1.模板特化 函数模板也可以特化,特化要符合模板参数类型 2.模板偏特化(局部 ...

  4. C++知识点62——模板实参推断与函数模板的特化

    一.函数指针与模板实参推断 可以用函数模板初始化一个函数指针或给一个函数指针赋值 示例 template <typename T> int comp(const T &a, con ...

  5. C++模板之特化与偏特化详解

    2019独角兽企业重金招聘Python工程师标准>>> C++函数模板与类模板实例解析_C 语言_脚本之家 http://www.jb51.net/article/53746.htm ...

  6. C++ 模板偏特化-来自STL的思考

    之前学习STL时接触过一段时间的模板,模板是C++泛型编程编程的基础 STL从头到尾都是模板泛型编程,我觉得用的最巧妙的就是在traits萃取技巧时用到的模板偏特化 先简要回顾一下模板吧,模板主要分为 ...

  7. c++中函数模板的显示具体化

    函数模板的显示具体化. 函数模板存在局限性,当定义函数模板时,我们始终假定函数体中的语句是合法的.例如定义如下函数模板: template <typename T> T add(T x, ...

  8. C++ 模板全特化中的函数特化

    转载:http://blog.csdn.net/rain_qingtian/article/details/15815251 [cpp] view plaincopy print? #include  ...

  9. 【C++模板】特化与偏特化 template [partial] specialization

    1 template specialization 模板特化 一般情况下类模板定义如下: template<class Window, class Controller> class Wi ...

最新文章

  1. 马尔可夫模型与条件随机场模型
  2. OA办公系统使用之:Tomcat与mysql的几个常见问题
  3. SegmentFault 技术周刊 Vol.17 - 听说你还没用上 AngularJS
  4. 【转】Monkey测试6-Monkey Test Log
  5. BLE控制器之物理层特性
  6. 计算机动画整个的发展历史,三维动画的发展史
  7. 高清、免版权美图资源大全
  8. EF Code First 简单的示例
  9. 推荐12个绚丽的CSS3图片悬停效果
  10. 信息学奥赛一本通 1143:最长最短单词 | OpenJudge NOI 1.7 25
  11. C函数形参列表与汇编寄存器的对应关系
  12. python计算计算时间_用Python向孩子介绍计算思维
  13. 关于x210开发板和主机、虚拟机ping通问题
  14. nslookup测试网络命令
  15. Django的下载与基本操作
  16. 软考网络工程师教程第五版(2018年最新版)
  17. 数据挖掘 NLP 之 文本挖掘 文本处理 通用流程
  18. 面部捕捉技术_新功能要来!苹果收购面部捕捉技术公司Faceshift
  19. fpga板子怎么和电脑连_干货教程 | 手把手教你如何使用Multisim对Digilent FPGA开发板进行编程...
  20. L9954LXP_特殊功能,车门模块驱动器

热门文章

  1. layui报错Uncaught TypeError: tree is not a function
  2. 嵌入式就业前景--应用领域
  3. 神奇的算法(一):欧几里德算法
  4. 大学python搜题软件_2020中国大学MOOC的APP慕课用Python玩转数据期末考试搜题公众号答案...
  5. php授权系统原理,Mysql权限系统工作原理-PHP教程,PHP基础
  6. 基于云的先进计划与调度系统的框架与部署
  7. 从原理到接法全面了解三相电
  8. python open报错:‘gbk‘ codec can‘t decode byte 0xbd in position xxxx: illegal multibyte sequence
  9. 波音737事故,软件化要不要“背锅”?
  10. python自动买股票_用python可以做哪些有趣的事--我:选股票