我们知道,当函数之间的函数体的整体逻辑相同c++模板类,而只是函数参数类型不同,特别是参数个数不同时,我们可以使用函数重载。对于类型不同的情形,更好的方式是函数模板,将类型参数化(可以简单理解为,函数模板的参数只是一个占位符,调用时可用具体的类型替换)。当然类也是如此,也就是类模板。
但存在的问题是c++模板类,一个统一的函数或模板并不一定能在所有类型实例下正常工作,这时就需要定义对于特定类型的特定模板实现版本。
模板特化不同于模板的实例化,模板参数在某种特定类型下的具体实现称为模板的特化。模板特化有时也称之为模板的具体化,分别有函数模板特化和类模板特化。
1 函数模板特化
以下是一个函数模板特化的实例:
#include #include using namespace std; template // 普通函数模板 T Max(T t1,T t2){ return (t1>t2)?t1:t2; } typedef const char* CCP; template // 函数模板特化 CCP Max(CCP s1,CCP s2){ return (strcmp(s1,s2)>0)?s1:s2; } int main(){ int i=Max(10,5); // 调用普通函数模板 const char* p=Max("very","good"); // 调用特化函数模板 cout<<"i:"<<i<<endl; // i:10 cout<<"p:"<<p<<endl; // p:very }
函数模板特化也可以使用函数重载来实现:
除了定义函数模板特化版本外,还可以直接给出模板函数在特定类型下的重载形式(普通函数)。使用函数重载可以实现函数模板特化的功能,也可以避免函数模板的特定实例的失效。例如,把上面的模板特化可以改成如下重载函数。
typedef const char* CCP; CCP Max(CCP s1,CCP s2){ return (strcmp(s1,s2)>0)?s1:s2; }
2 类模板的特化和偏特化
定义模板对于特定类型的特定实现版本时,如果特定类型是具体类型(如char*),称为模板特化或整体特化,如果是一类的具体类型(如T*),称为模板部分特化,或偏特化。
模板特化不同于模板的实例化,模板参数在某种特定类型下的具体实现称为模板的特化。模板特化有时也称之为模板的具体化,分别有函数模板特化和类模板特化。#include #include template class Storage { private: T m_value; public: Storage(T value) { m_value = value; } ~Storage() { } void print() { std::cout << m_value << 'n'; } }; template // Partial-specialization偏特化(m_value为T*) class Storage { private: T* m_value; public: Storage(T* value) { m_value = new T(*value); } ~Storage() { delete m_value; } void print() { std::cout << *m_value << 'n'; } }; template //Full specialization特化(m_value为char*) Storage::Storage(char* value) { // 计算value长度length int length = 0; while (value[length] != '') ++length; ++length; // +1 to account for null terminator m_value = new char[length]; //为value动态分配内存 for (int count = 0; count < length; ++count) //值复制入动态内存块 m_value[count] = value[count]; } template //Full specialization特化的析构(m_value为char*) Storage::~Storage() { delete[] m_value; } // Full specialization特化的函数print()(m_value为char*) // 如果没有特化,输出一个Storage会调用Storage::print(), 只输出首字符 template void Storage::print() { std::cout << m_value; } int main() { Storage myint(5); // 非特化函数模板调用 myint.print(); //5 int x = 7; Storage myintptr(&x); // 偏特化函数模板调用 x = 9; myintptr.print(); // 如果没有偏特化模板定义,会输出9而不是7 char *name = new char[40]; strcpy(name, "Alex"); Storage myname(name);//特化函数模板调用 delete[] name; myname.print(); //输出Alex }
可以使用在线编译器编译运行:
-End-
限时特惠:本站每日持续更新海量设计资源,一年会员只需29.9元,全站资源免费下载
站长微信:ziyuanshu688
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。