c++泛型编程

C++泛型编程

1. 基本概念

1.1 泛型编程(Generic Programming)

泛型编程是C++中一种重要的编程范式,它通过 参数化类型 来实现代码的通用性和复用性。

1.2 模板(Templates)

模板 是泛型编程的基础,允许编写与数据类型无关的代码。

模板分类:

  • 函数模板:参数化函数的参数类型。

  • 类模板:参数化类的成员类型。

  • 使用 template 关键字声明模板,typenameclass 声明模板类型,代表一个占位符类型,将在实例化时被具体类型替换。

template<typename T1 , typename T2 , ...>

2. 函数模板

2.1 函数模板语法

template<typename T>
void function( T arg1, T arg2 ) {
    // ...
}

2.2 函数模板的实例化

函数模板的实例化分为隐式实例化和显示实例化

  • 隐式实例化:编译器根据形参推演模板参数的实际类型。

  • 显示实例化:在函数名后<>中指定模板参数的实际类型。

template<typename T>
T add(const T& x , const T& y) {
    return x + y;
}

int main () {
    
    add(10 , 20);        // 隐式实例化 T为int
    add(1.1 , 2.2);      // 隐式实例化 T为double
    // add(10 , 1.1);    // 编译不通过,因为无法确定T为 int 还是 double 类型
    add<int>(10 , 1.1);  // 通过显示实例化解决

    return 0;
}

注意:对于非模板函数和同名函数模板,如果其他条件都相同,会优先调用非模板函数。

3. 类模板

3.1 类模板语法

template<typename T1 , typename T2 , ...>
class ClassName {
    // ...
};

3.2 类模板的实例化

类模板必须显示实例化。

template<typename T>
class vector {
    // ...
    private:
        T* start = nullptr;
        T* finish = nullptr;
        T* end_of_storage = nullptr;
};

int main () {
    
    // 显示实例化
    vector<int> v1; 
    vector<double> v1; 

    return 0;
}

4. 非类型模板参数

非类型模板参数是C++模板中一种特殊的参数类型,它允许在编译时传递值而不是类型作为模板参数。

非类型模板参数可以是以下类型之一

  • 整型

  • 指针或引用类型

  • C++20起支持浮点类型作为模板参数

  • C++20起支持类类型作为模板参数

template<typename T, size_t N = 10>
class Array {
    // ...
    T arr[N];
};

int main () {

    Array<> arr1;    // 使用缺省值的写法
    Array<5> arr2;
    Array<15> arr3; 

    return 0;
}

5. 模板的特化

模板特化是C++中为特定类型提供的模板定制。它允许我们为特定类型提供优化的或不同的实现,同时保留通用模板的灵活性。

5.1 函数模板的特化

函数模板也可以特化,但通常更推荐使用函数重载

函数模板特化步骤

  1. 特化必须声明在主模板之后。

  2. 关键字template后面接一对空的尖括号<>。

  3. 函数名后跟一对尖括号,尖括号中指定需要特化的类型。

  4. 特化模板的函数形参必须要和基础模板的函数形参完全相同。

template<typename T>
bool less(T left , T right) {
    return left < right;
}

// 对 int* 特殊化处理
template<>
bool less<int*>(int* left , int* right) {
    return *left < *right;
}

// 更推荐使用函数重载
bool less (int* left , int* right) {
    return *left < *right;
}

注意:函数模板不能偏特化,但可以通过函数重载实现。

5.2 类模板的特化

类模板特化分为全特化和偏特化两种形式。

  • 全特化:为模板的所有参数指定具体类型或值,完全特化整个模板。

  • 偏特化:只特化部分模板参数,或者对模板参数施加某种模式或约束。

5.2.1 全特化
// 主模板定义
template <typename T1, typename T2>
class MyClass {
    // 通用实现
};

// 全特化
template <>
class MyClass<int, double> {
    // 针对<int, double>的特化实现
};
5.2.2 偏特化(特化部分模板参数)
// 主模板定义
template <typename T1, typename T2>
class MyClass {
    // 通用实现
};

// 偏特化/半特化
template <typename T1>
class MyClass<T1, double> {
    // 针对<T1, double>的特化实现
};

注意:全特化和偏特化都存在时,全特化版本比偏特化版本具有更高的优先级。

5.2.3 偏特化(对模板参数施加某种约束)
// 主模板定义
template <typename T1, typename T2>
class MyClass {
    // 通用实现
};

// 偏特化/半特化
template <typename T1 , typename T2>
class MyClass<T1*, T2*> {
    // 针对<T1*, T2*>的特化实现
};


// 偏特化/半特化
template <typename T1 , typename T2>
class MyClass<T1&, T2&> {
    // 针对<T1&, T2&>的特化实现
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值