C++语言基础(19)-模板的显式具体化
应用背景:
例如有下面的函数模板,它用来获取两个变量中较大的一个:
template<class T> const T& Max(const T& a, const T& b){ return a > b ? a : b; }
请读者注意a > b
这条语句,>
能够用来比较 int、float、char 等基本类型数据的大小,但是却不能用来比较结构体变量、对象以及数组的大小,因为我们并没有针对结构体、类和数组重载>
。
另外,该函数模板虽然可以用于指针,但比较的是地址大小,而不是指针指向的数据,所以也没有现实的意义。
让模板能够针对某种具体的类型使用不同的算法(函数体或类体不同),这在 C++ 中是可以做到的,这种技术称为模板的显示具体化(Explicit Specialization)。
一.函数模板的显式具体化
#include <iostream> #include <string> using namespace std; typedef struct { string name; int age; float score; } STU; template<typename T> const T& Max(const T &a, const T &b); template<> const STU& Max<STU>(const STU &a, const STU &b); ostream & operator<<(ostream &out, const STU &stu); int main() { int a = 10; int b = 20; cout<<Max(a,b)<<endl; STU stu1 = {"Jack",16,95.5}; STU stu2 = {"Mike",17,90.0}; cout<<Max(stu1,stu2)<<endl; return 0; } template<typename T> const T& Max(const T &a, const T &b) { return a > b ? a : b; } template<> const STU& Max<STU>(const STU &a, const STU &b) { return a.score > b.score ? a : b; } ostream & operator<<(ostream &out, const STU &stu) { out<<stu.name<<", "<<stu.age<<", "<<stu.score; return out; }
运行结果:
20
Jack,16,95.5
语法格式为:
template<> const STU& Max(const STU& a, const STU& b);
二.类模板显式具体化
#include <iostream> #include <string> using namespace std; template<typename T1, typename T2> class Point { public: Point(T1 x, T2 y):m_x(x), m_y(y){} public: T1 getX() const {return m_x;} void setX(T1 x) {m_x = x;} T2 getY() const {return m_y;} void setY(T2 y) {m_y = y;} void display() const; private: T1 m_x; T2 m_y; }; // 这里要带上模板头 template<typename T1, typename T2> void Point<T1,T2>::display() const { cout<<"x="<<m_x<<", y="<<m_y<<endl; } // 类模板显式具体化(针对字符串类型的显式具体化) template<> class Point<char *, char *> { public: Point(char *x, char *y):m_x(x), m_y(y){} public: char* getX() const {return m_x;} void setX(char *x) {m_x = x;} char *getY() const {return m_y;} void setY(char *y) {m_y = y;} void display() const; private: char *m_x; char *m_y; }; // 注意!这里不能带模板头template<> void Point<char*, char*>::display() const { cout<<"x="<<m_x<<", y="<<m_y<<endl; } int main() { (new Point<int,int>(10,20))->display(); (new Point<int, char*>(20,"jack"))->display(); (new Point<char*,char*>("java","android"))->display(); return 0; }
运行结果:
x =10, y = 20
x = 20, y = jack
x = java, y = android
需要注意的是:在类模板的具体化中,成员方法的实例化是不能带模板头template<>的。
三.部分显式具体化
#include <iostream> using namespace std; // 类模板 template<typename T1, typename T2> class Point { public: Point(T1 x, T2 y):m_x(x), m_y(y){} public: T1 getX() const {return m_x;} void setX(T1 x){m_x = x;} T2 getY() const {return m_y;} void setY(T2 y){m_y = y;} void display() const; private: T1 m_x; T2 m_y; }; template<typename T1, typename T2> void Point<T1,T2>::display() const { cout<<"x="<<m_x<<", y="<<m_y<<endl; } template<typename T2> class Point<char*, T2> { public: Point(char *x, T2 y):m_x(x), m_y(y){} public: char *getX() const {return m_x;} void setX(char *x){m_x = x;} T2 getY() const {return m_y;} void setY(T2 y){m_y = y;} void display() const; private: char *m_x; T2 m_y; }; // 部分显式具体化还是需要加上模板头 template<typename T2> void Point<char*,T2>::display() const { cout<<"x="<<m_x<<" | y="<<m_y<<endl; } int main() { (new Point<int,int>(10,20))->display(); (new Point<char*,int>("jack",10))->display(); (new Point<char*,char*>("java","android"))->display(); return 0; }
运行结果:
x = 10, y = 20
x = jack | y = 10
x = java | y = android
注意:
部分显式具体化只能用于类模板,不能用于函数模板
如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。
分类:
C++基础知识
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库