16.模板的特化

模板的特化

​ 模板特化是C++中一种机制,允许为模板提供特定类型或特定值的定制实现。通常,模板是用于创建通用的数据类型或函数,但在某些情况下,我们可能希望为特定的类型或值提供特殊的实现。这就是模板特化发挥作用的地方。

​ 有两种主要类型的模板特化:类模板特化和函数模板特化。

函数模板特化

/*************************************************************************
        > File Name: test.cpp
        > Author:Xiao Yuheng
        > Mail:3312638794@qq.com
        > Created Time: Sun Nov 12 20:48:52 2023
 ************************************************************************/

#include <iostream>

using namespace std;

template<typename T>
T add(T a, T b) {
    return a + b;
}

template<>
int add<int>(int a, int b) {
    cout << "int" << endl;
    return a + b;
}

int main() {
    cout << add(3, 4) << endl;
    cout << add(3.1, 4.2) << endl;
    return 0;
}
  1. 通用模板函数 add

    template<typename T>
    T add(T a, T b) {
        return a + b;
    }
    

    这是一个通用的加法函数,用于接收两个相同类型的参数,并返回它们的和。

  2. int 类型的特化:

    template<>
    int add<int>(int a, int b) {
        cout << "int" << endl;
        return a + b;
    }
    

    这是 add 函数的特化版本,专门处理 int 类型的参数。在特化版本中,你添加了输出语句以提示你正在使用特化版本。

我们来看看这段代码的输出结果:

在这里插入图片描述

​ 可以发现当我们传入参数满足特化模板时,会优先调用特化模板。

类模板特化

/*************************************************************************
        > File Name: test1.cpp
        > Author:Xiao Yuheng
        > Mail:3312638794@qq.com
        > Created Time: Sun Nov 12 21:01:07 2023
 ************************************************************************/

#include <iostream>

using namespace std;

template<typename T, typename U>
class Test {
public:
    Test() {
        cout << "class Test<T, U> " << endl;
    }
};

template<>
class Test<int, double> {
public:
    Test() {
        cout << "class Test<int, double> " << endl;
    }
};

template<typename T>
class Test<int, T> {
public:
    Test() {
        cout << "class Test<int, T> " << endl;
    }
};

int main() {
    Test<double, int> a;
    Test<int, double> b;
    Test<int, string> c;

    return 0;
}

​ 在这个样例中我们有三种形式的模板,分别是正常的模板(template<typename T, typename U>),全特化版本(template<>),偏特化版本(template<typename T>),我们来看看这个样例的输出有什么不一样:

在这里插入图片描述

  • 我们可以发现第一个调用的是正常版本的模板

  • 第二个既满足正常的模板,也满足全特化版本,还满足偏特化版本,可是这里调用的是全特化版本的模板,说明全特化模板的优先级最高

  • 第三个既满足正常的模板,也满足偏特化版本,这里调用的是偏特化版本,说明偏特化版本的优先级比正常的模板高

    优先级:全特化 > 偏特化 > 正常版本

我们来自己实现一个样例:

/*************************************************************************
        > File Name: test.cpp
        > Author:Xiao Yuheng
        > Mail:3312638794@qq.com
        > Created Time: Sun Nov 12 20:48:52 2023
 ************************************************************************/

#include <iostream>

using namespace std;

class A {};
class B {};

int main() {
    cout << type_trais<int>::has_constructor << endl; // no
    cout << type_trais<A>::has_constructor << endl; // yes
    cout << type_trais<double>::has_constructor << endl; // no
    cout << type_trais<B>::has_constructor << endl; // yes
    cout << type_trais<string>::has_constructor << endl; // yes
    cout << type_trais<string *>::has_constructor << endl; // no
    return 0;
}

​ 让这段主函数可以正常运行,且输出的结果是我们后面所标识的:

完整代码:

/*************************************************************************
        > File Name: test.cpp
        > Author:Xiao Yuheng
        > Mail:3312638794@qq.com
        > Created Time: Sun Nov 12 20:48:52 2023
 ************************************************************************/

#include <iostream>

using namespace std;

template<typename T>
class type_trais {
public:
    static const char *has_constructor;
};
template<typename T>
const char *type_trais<T>::has_constructor = "yes";


template<typename T>
class type_trais<T *> {
public:
    static const char *has_constructor;
};
template<typename T>
const char *type_trais<T *>::has_constructor = "no";


template<>
class type_trais<int> {
public:
    static const char *has_constructor;
};
const char *type_trais<int>::has_constructor = "no";


template<>
class type_trais<double> {
public:
    static const char *has_constructor;
};
const char *type_trais<double>::has_constructor = "no";


class A {};
class B {};

int main() {
    cout << type_trais<int>::has_constructor << endl; // no
    cout << type_trais<A>::has_constructor << endl; // yes
    cout << type_trais<double>::has_constructor << endl; // no
    cout << type_trais<B>::has_constructor << endl; // yes
    cout << type_trais<string>::has_constructor << endl; // yes
    cout << type_trais<string *>::has_constructor << endl; // no
    return 0;
}

这段代码主要演示了C++中的模板特化,通过定义一个 type_traits 类模板,下面我将对代码进行详细解释:

  1. type_trais 类模板的通用定义:

    template<typename T>
    class type_trais {
    public:
        static const char *has_constructor;
    };
    template<typename T>
    const char *type_trais<T>::has_constructor = "yes";
    
  2. type_trais 类模板的部分特化(指针类型):

    template<typename T>
    class type_trais<T *> {
    public:
        static const char *has_constructor;
    };
    template<typename T>
    const char *type_trais<T *>::has_constructor = "no";
    
  3. type_trais 类模板的完全特化(int 和 double 类型):

    template<>
    class type_trais<int> {
    public:
        static const char *has_constructor;
    };
    const char *type_trais<int>::has_constructor = "no";
    
    template<>
    class type_trais<double> {
    public:
        static const char *has_constructor;
    };
    const char *type_trais<double>::has_constructor = "no";
    
  4. main 函数中的测试:

    int main() {
        cout << type_trais<int>::has_constructor << endl;         // 输出: no
        cout << type_trais<A>::has_constructor << endl;           // 输出: yes
        cout << type_trais<double>::has_constructor << endl;      // 输出: no
        cout << type_trais<B>::has_constructor << endl;           // 输出: yes
        cout << type_trais<string>::has_constructor << endl;      // 输出: yes
        cout << type_trais<string *>::has_constructor << endl;    // 输出: no
        return 0;
    }
    

    这样就可以实现我们主函数的所有功能。

简化版本

/*************************************************************************
        > File Name: test.cpp
        > Author:Xiao Yuheng
        > Mail:3312638794@qq.com
        > Created Time: Sun Nov 12 20:48:52 2023
 ************************************************************************/

#include <iostream>

using namespace std;

class yes_constructor {
public:
    static const char *has_constructor;
};
const char *yes_constructor::has_constructor = "yes";

class no_constructor {
public:
    static const char *has_constructor;
};
const char *no_constructor::has_constructor = "no";

template<typename T>
class type_trais : public yes_constructor {};


template<typename T>
class type_trais<T *> : public no_constructor {};


template<>
class type_trais<int> : public no_constructor {};


template<>
class type_trais<double> : public no_constructor {};


class A {};
class B {};

int main() {
    cout << type_trais<int>::has_constructor << endl; // no
    cout << type_trais<A>::has_constructor << endl; // yes
    cout << type_trais<double>::has_constructor << endl; // no
    cout << type_trais<B>::has_constructor << endl; // yes
    cout << type_trais<string>::has_constructor << endl; // yes
    cout << type_trais<string *>::has_constructor << endl; // no
    return 0;
}

用继承简单简化一下。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值