4-6类和函数的模板全特化、偏特化(局部特化)

目录

1.类模板特化

1.1类模板全特化

1.1.1常规全特化

1.1.2类模板偏特化(局部特化)

2.函数模板特化

2.1 函数模板全特化

2.2 函数模板不能偏特化

3.模板特化版本放置位置建议


1.类模板特化

特化:相反的是   泛化:模板,可以随便指定类型

特化:对特殊的类型(类型模板参数)进行特殊的对待。

1.1类模板全特化

1.1.1常规全特化

必须先有泛化版本才能存在特化版本。只要设计特化,就一定存在泛化

特化版本代码编译器会优先选择

#include <iostream>
#include <string>

using namespace std;

template <typename T,typename U>
struct TC // 泛化的TC类模板
{
    TC()
    {
        cout << "泛化版本构造函数" << endl;
    }

    void functest()
    {
        cout << "泛化版本" << endl;
    }
};

// 当T与U这两个类型模板参数都为int类型时,我们希望做一个特化版本
// 全特化就是所有类型模板参数,都需要用具体的类型代表
// 全特化表示所有类型模板参数都用具体类型代表,
// 所以这里template后面的<>里为空
template <>
struct TC<int,int> // 上面的T绑定到第一个int,上面的U绑定到第二个int
{
    TC()
    {
        cout << "特化版本构造函数" << endl;
    }
    // 对特化版本进行单独处理
    void functest()
    {
        cout << "int,int的特化版本" << endl;
    }
};

// 当T与U这两个类型模板参数都为int类型时,我们希望做一个特化版本
// 全特化就是所有类型模板参数,都需要用具体的类型代表
// 全特化表示所有类型模板参数都用具体类型代表,
// 所以这里template后面的<>里为空
template <>
// 上面的T绑定到第一个double,上面的U绑定到第二个int
struct TC<double, int>
{
    void functest()
    {
        cout << "double,int的特化版本" << endl;
    }
};

int main()
{
    // 调用int,int特化版本
    TC<int, int> dc;
    dc.functest();

    // 调用泛化版本
    TC<char, int> tchar;
    tchar.functest();

    system("pause");
    return 0;
}

特化成员函数而不是模板

#include <iostream>
#include <vector>
#include <string>
#include <map>
using namespace std;
template <typename T , typename U>
struct TC   //泛化的TC版本
{
    TC()
    {
        cout <<"泛化版本的构造函数" << endl;
    }
    void function()
    {
        cout << "泛化版本" << endl;
    }
};

template <>
void TC<int ,int>:: function ()
{
    cout << "int int的function()特化版本" << endl;
}

int main()
{
    TC<int,int> tech; //调用泛化版本的构造函数
    tech.function();  //因为我们特化了int ,int类型的
}

1.1.2类模板偏特化(局部特化)

偏特化从两个方面说起:一个是从 模板数量,一个是从模板参数范围上。

#include <iostream>
#include <vector>
#include <string>
#include <map>
using namespace std;
template <typename T , typename U ,typename W>
struct TC
{
    void functest()
    {
        cout << "泛化版本"  <<endl;
    }
};
//从参数数量上进行偏特化,我们现在绑定2个类型模板参数
template <typename U>
struct TC<int,U,double> //这里可以跳转
{
    void functest()
    {
        cout <<"偏特化版本" <<endl;
    }
};
int main()
{
    //数量上
    TC<double,int,double> tech;
    tech.functest();
    TC<int ,int ,double> tech1;
    tech1.functest();
}
#include <iostream>
#include <string>

using namespace std;

template <typename T>
struct TC // 泛化的TC类模板
{
    TC()
    {
        cout << "泛化版本构造函数" << endl;
    }

    void functest()
    {
        cout << "泛化版本" << endl;
    }
};

// 模板参数范围上的特化版本
template <typename T>
struct TC<const T>
{
    TC()
    {
        cout << "const类型特化版本构造函数" << endl;
    }

    void functest()
    {
        cout << "const类型特化版本" << endl;
    }
};

// 模板参数范围上的特化版本
template <typename T>
struct TC<T*>
{
    TC()
    {
        cout << "指针类型偏特化版本构造函数" << endl;
    }

    void functest()
    {
        cout << "指针类型特化偏版本" << endl;
    }
};

int main()
{
    // 模板参数范围上的特化版本
    TC<const int> dc;
    dc.functest();

    // 模板参数范围上的特化版本
    TC<int *> dx;
    dx.functest();

    system("pause");
    return 0;
}

    模板参数范围上,int ---- const int (比int小)
    T到T*,缩小了
    T到 T& T&&  (右值引用)

2.函数模板特化

2.1 函数模板全特化

全特化函数模板实际上等价于实例化 一个函数模板,并不是等价于一个函数重载。

//void tfunc<int ,double>(int &,double &){}  全特化,等价于实例化一个函数模板

//void tfunc (int &tmp1,double &temp2) {} 函数重载

#include <iostream>
#include <string>

using namespace std;

// 函数模板泛化版本
template <typename T,typename U>
void tfunc(T &tmprv, U &tmprv2)
{
    cout << "tfunc泛化版本!" << endl;
    cout << tmprv << endl;
    cout << tmprv2 << endl;
}

// 函数模板全特化版本 T =int ,U = double
template <>
void tfunc(int &tmprv, double &tmprv2)
{
    cout << "tfunc特化版本!<int, double>" << endl;
    cout << tmprv << endl;
    cout << tmprv2 << endl;
}

// 函数模板重载函数
void tfunc(int &tmprv, double &tmprv2)
{
    cout << "tfunc重载函数版本" << endl;
    cout << tmprv << endl;
    cout << tmprv2 << endl;
}

int main()
{
    const char *p = "I Love China!";
    int i = 12;
    // 泛化版本
    tfunc(p, i);

    // 特化版本
    int x = 1; double y = 3;
    tfunc(x, y);
    //编译器选择最合适的版本:普通函数 > 特化版本 > 泛化版本;

    //全特化函数模板实际等价于实例化一个函数模板,并不是函数重载。
    //void tfunc<int, double>(int &tmpv1, double &tmpv2){ }
    //void tfucn(int &tmpv1, double &tmpv2) { }

    system("pause");
    return 0;
}

//编译器选择最合适:普通优先,特化版本,泛化版本

//数组类型模板参数,比 指针类型模板参数更合适。

如果你传递字符串给函数模板,函数模板的特化版本中有 数组类型模板参数, 指针类型模板参数。

编译器会认为 数组类型模板参数比指针类型模板参数更合适。 所以编译器会为你选择数组类型的模板参数 的特化版本。

2.2 函数模板不能偏特化

写法就冲突了:C++不支持函数模板偏特化,只能全特化。

3.模板特化版本放置位置建议

模板定义。实现都放在一个.h的文件中

模板的特化版本泛化版本,实现都放在同一个.h文件中

.h文件中前边放泛化版本,后边放特化版本。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值