C++ 泛编程 —— 函数模板(中)

C++ 泛编程 ------ 函数模板(中)

函数模板的具体化

可以提供一个具体化的函数定义,当编译器找到与函数调用匹配的具体化定义时,将使用该定义,不再寻找模板。
具体化(特例化、特化)的语法:

cpp 复制代码
template<> void 函数模板名<数据类型>(参数列表)
template<> void 函数模板名 (参数列表)
{
	// 函数体。
}

请看如下示例代码:

cpp 复制代码
#include <iostream>
using namespace std;

class Car{
public:    
    string brand_;
    int speed_;
    float acceleration_;
};

template<typename T> 
void change(T& t1, T& t2){
    T tmp = t1;
    t1 = t2;
    t2 = tmp;
}

// 现在的需求是:只交换 Car 类对象中的 speed_ 属性值,不交换其他属性值。
// 具体化函数的代码如下
// template<> void change<Car>(Car& c1, Car& c2) // 第一种写法
template<> void change(Car& c1, Car& c2) { // 第二种写法 交换两个Car类对象的speed_属性值
    int tmp = c1.speed_;
    c1.speed_ = c2.speed_;
    c2.speed_ = tmp;
}

int main(){
    int a = 10, b = 20;
    change<int>(a, b);
    cout << "a = " << a << ", b = " << b << endl;
    Car c1 = {"BMW", 20, 3.5};
    Car c2 = {"Audi", 30, 4.5};
    change(c1, c2);
    cout << "c1.brand_ = " << c1.brand_ << ", c2.brand_ = " << c2.brand_ << endl;
    cout << "c1.speed_ = " << c1.speed_ << ", c2.speed_ = " << c2.speed_ << endl;

    return 0;
}

编译运行的结果如下:

a = 20, b = 10

c1.brand_ = BMW, c2.brand_ = Audi

c1.speed_ = 30, c2.speed_ = 20

对于具体化函数来说,不管是函数的声明还是函数体中,都是具体的数据类型,没有通用的数据类型了。

对于给定的函数名,它可以是普通函数函数模板具体化的函数模板,以及它们的重载版本。如果多种函数都能匹配上,那编译器会使用哪个函数呢?编译器使用各种函数的规则:

  1. 具体化优先于常规模板,普通函数优先于具体化和常规模板。
  2. 如果希望使用函数模板,可以用空模板参数强制使用函数模板。
  3. 如果函数模板能产生更好的匹配,将优先于普通函数。

对于前两条规则,给出示例代码,大家可以自行选择注释某个版本的函数代码,来测试一下各个版本函数代码的使用规则:

cpp 复制代码
#include <iostream>
using namespace std;

// 普通版本函数
void show(int n1, int n2) {
    cout << "使用普通版本函数" << endl;
}

// 常规函数模板
template <typename T>
void show(T n1, T n2) {
    cout << "使用常规函数模板" << endl;
}

// 函数模板的具体化版本
template <>
void show(int n1, int n2) {
    cout << "使用函数模板的具体化版本" << endl;
}

int main() {
    show(111, 222);
    show<>(111, 222);

    return 0;
}

编译运行结果如下:

使用普通版本函数

使用函数模板的具体化版本

对于第三条规则:如果函数模板能产生更好的匹配,将优先于普通函数,示例代码如下:

cpp 复制代码
#include <iostream>
using namespace std;

// 普通版本函数
void show(int n1, int n2) {
    cout << "使用普通版本函数" << endl;
}

// 常规函数模板
// template <typename T>
// void show(T n1, T n2) {
//     cout << "使用常规函数模板" << endl;
// }

int main() {
    show('a', 'b'); // 字符可以转换成整数

    return 0;
}

编译运行结果如下:

使用普通版本函数

如果取消注释,编译运行结果如下:

使用常规函数模板

原因解释:实参是字符ab,与常规函数模板可以完全匹配,不需要转换,比普通函数匹配度更好。所以,编译器选择了常规函数模板。

C++ 泛编程 ------ 函数模板(上)

C++ 泛编程 ------ 函数模板(下)

感谢浏览,一起学习!

相关推荐
qq_1998868723 分钟前
第7板块·第3节:CUTLASS 的 GEMM 实现与优化策略
c++·人工智能·gpu算力·cuda
hetao173383726 分钟前
2026-09-17 hetao1733837 的刷题记录
c++·算法
blue_ice .29 分钟前
Verilog DDS 数字信号发生器:DAC 输出模拟波形与 ADC 回采观测
开发语言·单片机·嵌入式硬件·fpga开发
远翔调光芯片^138287988721 小时前
ECP5702能芯科技PD取电芯片在市场上的优势有哪些?
开发语言·人工智能·单片机·嵌入式硬件·智能家居
shada2 小时前
Boost.Process v2 在旧内核上报 `assign: Bad file descriptor`
c++
泡海椒2 小时前
规则引擎对比:JQuick-Java vs Drools 轻量场景选型对比
java·开发语言
2601_949950632 小时前
练题簿在线练题全流程:从资料导入到模拟考试与错题复盘
学习·考研·小程序·刷题·小程序推荐
泡泡鱼(敲代码中)2 小时前
Python 容器类型学习笔记:列表、元组、字典、集合
开发语言·笔记·python·pycharm
别动我齐刘海2 小时前
ROS2 Jazzy + C++ 实战路线——基础学习2
c++·人工智能·vscode·python·学习·机器学习·机器人
2501_933670792 小时前
平台招商运营校招能力模型:数据分析、SQL与增长场景拆解
开发语言