【C++】模板具体化、实例化、特化整理总结

2023-12-13 23:16:42


模板的具体化分为隐式实例化)、显式实例化和显式具体化)。 模板以泛型的方式描述函数(类),而具体化是使用具体的类型生成函数(类)声明。
显式实例化和显式具体化的区别在于显式实例化只需要写声明不需要写定义,显式实例化的定义与隐式实例化一样由编译器生成。

模板具体化

实例化(隐式实例化)

而是对于实例化模板参数的每种类型,都从模板产生出一个不同的实体。
这种用具体类型代替模板参数的过程叫做实例化。它产生了一个模板的实例。
编译器使用模板为特定类型生成函数(类)定义时,得到的就是模板实例。

template <typename T>
T const& max (T const& a, T const& b)
{
    return  a < b ? b : a;
}

实例化其实就是模板最普通的写法

显式实例化

使用关键字template并指出所需类型来声明类时,编译器将生成类声明的显式实例化。
(显示生成一个类型的实例)

template <typename T>
inline T max (T a, T b)
{
    return  a < b  ?  b : a;
}
template int max<int>(int a, int b);    //显式实例化,指定编译器生成int类型的模板定义
template int max<>(int a, int b);   //简写
template int max(int a, int b); //简写

显式实例化只是一个声明,让编译器用具体的类型生成函数定义或类定义。

用处:
在多文件编译连接时生成实例

//t1.h
template <typename T>
void f(T x);

//t1.cpp
#include "te.h"
#include <iostream>
template <typename T>
void f(T x)
{
    std::cout << x << std::endl;
}
template void f<int>(int);//显式实例化int

//main.cpp
#include "te.h"
#include <iostream>

int main()
{
  f(6); //编译成功,输出6
  //编译失败,undefined reference to `void f<char>(char)'
  f('6'); 
  return 0;
}

上述代码用显示实例化生成了int的函数而没有生成char的,从而报错char类型的未定义

显式具体化(特化)

函数模板特化指函数模板在模板参数为特定类型下的特定实现
模板的特化和函数类模板的重载类似,你可以依次重写这个函数或者类, 也可以只特化某个成员(片特化),也可以特化整个类(全特化)

具体化(全特化)

在起始处声明一个 template<>,接下来声明用来特化类模板的类型。这个类型被用作模板实参,且必须在类名的后面直接指定

template<> 
class A<int>{
    ....
};

进行类模板的全特化时,每个成员函数都必须重新定义为普通函数,原来模板函数中的每个T也相应地被进行特化的类型取代:

#include <iostream>
//模板
template <typename T>
class A{
public:
  void get(){std::cout << "common" << std::endl;}
};

template<>
class A<int>{
public:
  void get(){std::cout << "int template" << std::endl;}
};

int main()
{
  A<std::string> a;
  a.get(); //common
  A<int> aa;
  aa.get(); //int template
  return 0;
}

注意:
全特化和由模板生成的实例化不能存在于同一个程序中。

template <typename T>
class A {
public:
};

template class A<double>;

//错误,必须在其首次使用之前对 类 \"A<double>\" 进行显式专用化
template<> 
class A<double> 
{
};
  • 函数模板特化
template<typename T>
int f(T) { return 1; }

template<> int f<int>(int) { return 3; }    //完整写法
template<> int f(int) { return 3; } //简写,省略了<int>
部分具体化(部分特化、偏特化)

模板偏特化是模板特化的一种特殊情况,指显示指定部分模板参数而非全部模板参数,或者指定模板参数的部分特性分而非全部特性,也称为模板部分特化。

//类模板
template <typename T1, typename T2>
class MyClass {
...
};

//局部特化:两个模板参数具有相同的类型
template <typename T>
class MyClass<T,T> {
...
};

//局部特化:第2个模板参数的类型是int
template<typename T>
class MyClass<T,int> {
...
};

局部特化:两个模板参数都是指针类型。
template<typename T1,typename T2>
class MyClass<T1*,T2*>{
...
};

调用:

Myclass<int,float> mif;   //使用MyClass<T1,T2>
MyClass<float,float> mff;  //使用MyClass<T,T>
MyClass<float,int>  mfi;   //使用MyClass<T,int>
MyClass<int*,float*> mp;   //使用MyClass<T1*,T2*>

实例

#include <iostream>
#include <string>

template <typename T1, typename T2>
class MyClass 
{
public:
    MyClass(const T1& t1, const T2& t2) { std::cout << "111: " << t1 << std::endl; }
};

//显示具体化、特化
template<>
class MyClass<std::string, std::string>
{
public:
    MyClass(const std::string& t1, const std::string& t2) { std::cout << "222 : " << t1 << std::endl; }
};

//部分特化
template <typename T1>
class MyClass<T1, double> 
{
public:
    MyClass(const T1& t1, const double& t2) { std::cout << "333 : " << t1 << std::endl; }
};

//显示实例化
template class MyClass<std::string, int>;

int main()
{
    MyClass<char[3],std::string> class2("s2", "s22"); 
    MyClass<std::string,std::string> class3("s3", "s33"); 
    MyClass<std::string,double> class4("s4", 3.14); 

    return 0;
}

输出

111: s2
222 : s3
333 : s4

文章来源:https://blog.csdn.net/qq_60755751/article/details/134984138
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。