C++之函数模板、具体化(特化)

函数模板是通用的函数描述,使用任意类型(泛型)来描述函数。
编译的时候,编译器推导实参的数据类型,根据实参的数据类型和函数模板,生成该类型的函数定义。
生成函数定义的过程被称为实例化。

下面是一个简单的例子

void Swap(T &a,T &b)
{
        T tmp=a;
        a=b;
        b=tmp;
}
void test()
{
    int a=1;
    int b=2;
    swap(a,b);
    swap<int>(a,b);
}

注意

1)可以为类的成员函数创建模板,但不能是虚函数和析构函数。
2)使用函数模板时,必须明确数据类型,确保实参与函数模板能匹配上。
3)使用函数模板时,推导的数据类型必须适应函数模板中的代码。
4)使用函数模板时,如果是自动类型推导,不会发生隐式类型转换,如果显式指定了函数模板的数据类型,可以发生隐式类型转换。
5)函数模板支持多个通用数据类型的参数。
6) 函数模板支持重载,可以有非通用数据类型的参数

针对第四点,我们看如下代码

template<typename T>
T ADD(T a,T b)
{
    return a+b;
}
void test()
{
    int a=1,b=2;
    char c=20;
    int sum1=ADD(a,b);    //隐式显示都可以
    int sum2=ADD<int>(a,c);//必须显式调用,char可以隐式转换成int
}

函数模板的具体化

具体化(特例化、特化)的语法:

template<> void 函数模板名<数据类型>(参数列表)
template<> void 函数模板名 (参数列表)
{
    // 函数体。
}
编译器使用各种函数的规则:
1) 具体化优先于常规模板,普通函数优先于具体化和常规模板
2)如果希望使用函数模板,可以用空模板参数强制使用函数模板。
3)如果函数模板能产生更好的匹配,将优先于普通函数。
#include <iostream>         // 包含头文件。
using namespace std;        // 指定缺省的命名空间。
class Object
{
public:
    string m_name;
    Object(string name) :m_name(name) {}
};
void Swap(int a, int b)      // 普通函数。
{
    cout << "使用了普通函数。\n";
}

template <typename T>
void Swap(T a, T b)          // 函数模板。
{
    cout << "使用了函数模板。\n";
}

template <>
void Swap(int a, int b)     // 函数模板的具体化版本。
{
    cout << "使用了具体化的函数模板。\n";
}

int main()
{
    Swap(1, 2);    //普通函数优先于具体化和常规模板
    Swap<>(1, 2);    //使用一对空尖括号代表强制使用具体化函数模板
    Swap('c', 'd');
    Object obj1("张三"), obj2("李四");
    Swap(obj1, obj2);    //函数模板
    return 0;
}
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
函数模板是一种通用的函数定义,它允许编写能够处理多种不同类型的数据的函数函数模板的定义以关键字 `template` 开头,后面跟着模板参数列表和函数的原型。 例如,以下是一个简单的函数模板,用于交换两个值: ```c++ template <typename T> void swap(T& a, T& b) { T temp = a; a = b; b = temp; } ``` 上述代码中,`typename T` 表示这是一个类型参数,可以接受任何类型的数据。在函数体中,我们只是简单地交换了两个值。 使用函数模板时,需要将具体的类型传递给模板参数,例如: ```c++ int a = 5, b = 10; swap<int>(a, b); // 交换 a 和 b 的值 ``` 在上述示例中,我们显式地将 `int` 作为模板参数传递给 `swap` 函数函数模板还支持全特化,这意味着我们可以为特定的类型提供一个特定的实现。全特化使用关键字 `template<>` 手动指定模板参数列表中的类型,并提供一个特定的函数实现。 例如,以下是一个针对 `char` 类型的 `swap` 函数的全特化: ```c++ template <> void swap<char>(char& a, char& b) { char temp = a; a = b; b = temp; std::cout << "Swapping chars!" << std::endl; } ``` 上述代码中,我们使用了 `template<>` 关键字显示地声明了一个全特化函数,指定了模板参数为 `char`。 当我们调用 `swap` 函数,并将 `char` 类型的变量作为参数传递时,编译器将自动选择调用这个全特化版本的函数。 需要注意的是,全特化版本的函数应该在头文件中进行声明和定义,以便编译器能够正确地实例化这些函数

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小谢%同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值