C++函数与类模板详解

目录

一、模板概述

二、模板实例

二、函数模板

(一)定义与实例化

(二)模板参数的显式指定

(三)模板参数的默认值

(四)模板特化

1. 全特化

2. 偏特化

三、类模板

(一)定义与实例化

(二)模板参数的显式指定

(三)模板参数的默认值

(四)模板特化

1. 全特化

2. 偏特化

四、全特化与偏特化的区别

(一)作用对象

(二)模板参数

(三)实例化优先级

五、模板的优缺点

(一)优点

(二)缺点

六、总结


一、模板概述

C++模板是一种强大的语言特性,用于实现泛型编程。它允许程序员定义通用的函数和类,这些函数和类可以使用任意类型作为参数,从而提高代码的复用性和灵活性。模板分为函数模板和类模板两种类型。

二、模板实例

#include <iostream>
using namespace std;

// 函数主模板
template <typename T>
void print(T value)
{
    cout << "General template: " << value << endl;
}
// 函数模板的全特化
template <>
void print<int>(int value)
{
    cout << "Specialized for int: " << value << endl;
}

// 类主模板
template <typename T, typename U>
class Pair
{
public:
    T first;
    U second;

    Pair(T t, U u) : first(t), second(u) { cout << "General Pair" << endl; }
};
// 类模板的偏特化
template <typename U>
class Pair<int, U>
{
public:
    int first;
    U second;

    Pair(int t, U u) : first(t), second(u) { cout << "Partial specialization for int, U" << endl; }
};
// 类模板的偏特化
template <typename T>
class Pair<T, double>
{
public:
    T first;
    double second;

    Pair(T t, double u) : first(t), second(u) { cout << "Partial specialization for T, double" << endl; }
};
// 类模板的全特化
template <>
class Pair<char, int>
{
public:
    char first;
    int second;

    Pair(char t, int u) : first(t), second(u) { cout << "specialization for char, int" << endl; }
};

int main()
{
    print(10); // 调用函数全特化版本
    print(3.14); // 调用函数通用模板版本

    Pair<char, int> charIntPair('a', 2); // 调用类全特化版本
    Pair<char, double> charDoublePair('a', 3.14); // 调用类偏特化版本
    Pair<int, double> intDoublePair(1, 2.71); // 调用类偏特化版本
    Pair<int, char> intCharPair(1, 'b'); // 调用类通用模板版本

    return 0;
}

输出结果

Specialized for int: 10
General template: 3.14

specialization for char, int
Partial specialization for T, double
Partial specialization for int, u
General Pair

二、函数模板

(一)定义与实例化

函数模板是一种通用函数的定义方式,它允许函数操作的数据类型作为参数传递。函数模板的定义格式如下:

template <typename T>
返回类型 函数名(参数列表)
{
    // 函数体
}

在调用函数模板时,模板参数类型可以由编译器自动推断,也可以显式指定。

示例代码

template <typename T>
void print(T value)
{
    cout << value << endl;
}

int main()
{
    print(10); // 实例化为 print<int>
    print(3.14); // 实例化为 print<double>
}

(二)模板参数的显式指定

在调用函数模板时,可以显式指定模板参数的类型:

print(10); // 实例化为 print<int>
print(3.14); // 实例化为 print<double>

(三)模板参数的默认值

函数模板的模板参数可以有默认值:

template <typename T = int>
void print(T value)
{
    cout << value << endl;
}

(四)模板特化

模板特化是指为特定的模板参数类型提供一个特殊的实现。函数模板不支持偏特化,但可以通过全特化重载来实现类似的功能。

1. 全特化

全特化是指为模板的所有模板参数提供特定的类型实现。

// 原始版本
template <typename T>
void print(T value)
{
    cout << "General template: " << value << endl;
}
// 特化版本
template <>
void print<int>(int value)
{
    cout << "Specialized for int: " << value << endl;
}
2. 偏特化

实际上,函数模板不支持偏特化,但可以通过全特化重载来实现类似的功能。

template <typename T>
void print(T value)
{
    cout << "General template: " << value << endl;
}

void print(int value)
{
    cout << "overriding: " << value << endl;
}

三、类模板

(一)定义与实例化

类模板是一种通用类的定义方式,它允许类的成员变量和成员函数操作的数据类型作为参数传递。类模板的定义格式如下:

template <typename T>
class 类名
{
    // 类的成员变量和成员函数
};

在实例化类模板时,需要为模板参数指定具体的类型。

示例代码

#include <iostream>
using namespace std;

template <typename T>
class Stack
{
private:
    T data[100];
    int top;

public:
    Stack() : top(-1) {}
    ~Stack() {}
};

int main()
{
    Stack<int> intStack;
    Stack<double> doubleStack;
    return 0;
}

Stack<int> 和Stack<double> 实例化 Stack 类模板生成的具体类

(二)模板参数的显式指定

在实例化类模板时,可以显式指定模板参数的类型:

Stack<int> intStack; // 显式指定模板参数类型为 int
Stack<double> doubleStack; // 显式指定模板参数类型为 double

(三)模板参数的默认值

类模板的模板参数可以有默认值:

template <typename T = int>
class Stack
{
    // 类的成员变量和成员函数
};

(四)模板特化

模板特化是指为特定的模板参数类型提供一个特殊的实现。特化分为全特化和偏特化,其中将模板参数全部写死为全特化,即固定了具体类型;而偏特化后的模板参数表里仍然存在可变的部分。假设只有一个参数,参数类型为int*属于全特化,参数类型T*是偏特化。

1. 全特化

全特化是指为模板的所有模板参数提供特定的类型实现。

// 原始模板
template <typename T>
class Stack
{
public:
    void push(T value) { cout << "General push: " << value << endl; }
};

// 全特化
template <>
class Stack<int>
{
public:
    void push(int value) { cout << "Specialized push for int: " << value << endl; }
};
2. 偏特化

偏特化是指为模板的部分模板参数提供特定的类型实现,而其他模板参数仍然保持通用。偏特化只能用于类模板。

// 1. 原始模板(主模板)
template<typename T, typename U>
class Pair { /* 通用实现 */ };

// 2. 偏特化:固定第一个参数为 int
template<typename U>
class Pair<int, U> { /* 针对 int 的优化 */ };

// 3. 偏特化:两个参数都是指针
template<typename T, typename U>
class Pair<T*, U*> { /* 指针特化 */ };

// 4. 偏特化:第二个参数是数组
template<typename T, size_t N>
class Pair<T, T[N]> { /* 数组特化 */ };

四、全特化与偏特化的区别

(一)作用对象

全特化:可以应用于函数模板和类模板。

偏特化:只能应用于类模板。

(二)模板参数

全特化:所有模板参数都被指定为具体类型。

偏特化:部分模板参数被指定为特定类型,其他模板参数仍然保持通用。

(三)实例化优先级

当存在全特化、偏特化和通用模板时,优先级顺序为:

全特化 > 偏特化 > 通用模板
 

五、模板的优缺点

(一)优点

代码复用性高:模板允许定义通用的函数和类,可以用于任意类型的数据,减少了代码冗余。

类型安全:模板在编译时会进行类型检查,确保模板参数类型与函数或类的使用方式一致,避免了类型错误。

性能优化:模板在编译时生成特定类型的代码,避免了运行时的类型转换和动态绑定,提高了程序的运行效率。

(二)缺点

编译时间增加:模板的使用会导致编译器生成大量的模板实例代码,增加了编译时间。

代码膨胀:模板实例化会生成多个版本的代码,可能导致代码体积增大。

调试困难:模板错误的诊断和调试相对复杂,因为编译器生成的模板实例代码可能难以理解。

六、总结

维度主模板偏特化全特化
模板参数全部泛型部分固定全部固定
适用对象类模板/函数模板仅类模板类模板/函数模板
语法template<typename T, typename U>template<typename U>template<>
优先级最低最高

C++模板是一种强大的语言特性,用于实现泛型编程。通过模板,可以定义通用的函数和类,提高代码的复用性和灵活性。函数模板和类模板的使用方式类似,都支持模板参数的显式指定、默认值和特化。模板特化分为全特化和偏特化两种类型,全特化可以应用于函数模板和类模板,而偏特化只能应用于类模板。合理使用模板可以提高代码的可维护性和可扩展性。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值