C++泛型编程

泛型编程

一种编程范式,目标是编写 类型无关 的代码

将算法和数据结构被设计成可以处理多种数据类型而不是针对特定类型进行硬编码

允许使用相同的代码逻辑处理不同类型的数据,从而提高代码的复用性和可维护性。


各语言对泛型编程的支持

C++:

  • 模板(函数模板类模板

Java:

  • 泛型方法泛型类

    public static <T> T add(T a, T b)
    //JAVA 泛型方法的基本介绍
    //1) public 与 返回值T中间<T>非常重要,可以理解为声明此方法为泛型方法
    //2) 只有声明了的方法才是泛型方法,泛型类中使用了泛型的成员方法并不是泛型方法
    //3) 表明该方法将使用泛型类型T,此时才可以在方法中使用泛型类型T
    //4) JAVA的泛型方法不能直接用于基本类型。


特化模板

从面向对象的角度来看,特化模板就相当于一个继承了通用模板的子类
C++ 的 类模板和函数模板,都支持模板特化

在语法层面,JAVA 没有 C++ 中模板特化的支持。但是依然可以通过继承和重载来模拟类似的效果。
当然,在实操中,JAVA开发人员进行泛型编程已属少见,更别说模拟C++特化模板。
况且,没有C++的知识,JAVA开发人员很可能没有特化模板的概念。


内部机制

JAVA 类型插除

类模板和泛型类的继承

C++ 中的实现

c++ 泛型编程有两种实现方式

  1. 模板
  2. 多态

一、模板

  • 函数模板
  • 类模板

二者均可以进行特化模板


代码示例

单个类型模板

注意 add(1,1.5); //错误,无法推导出模板参数类型,这个跟java有差异。

#include <iostream>
using namespace std;
template <typename T>
T add(T a, T b) {
    return a + b;
}
int main() {
    int a = 1, b = 2;
    double c = 1.5, d = 2.5;
    int sum_int = add(a, b);//3 // 编译器生成 int 特化版本
    double sum_double = add(c, d);//4 // 编译器生成 double 特化版本
    // add(1,1.5);//错误,无法推导出模板参数类型,这个跟java有差异。
    std::cout << "Sum int: " << sum_int << ", Sum double: " << sum_double << std::endl;
}

错误的JAVA写法
函数的申明没有问题,错误在于函数体中的a+b
因为Java泛型不支持基本类型,且+只能在基本类型中使用。因此,这种写法表示对两个类进行+运算,错误。

public static <T> T add(T a, T b) {
	return a+b;//错误
}

正确
允许 add(1.1, 2); 这个与C++有差异,因为这里的T都是Number的子类

public class func {
    public static void main(String[] args) {
        System.out.println("Hello World!");
        System.out.println(add(1, 2));//3.0
        System.out.println(add(1.1, 2.2));//3.3000000000000003
        System.out.println(add(1.1, 2));//3.1
        System.out.println(add(1, 2.2));//3.2
    }
    public static <T extends Number> double add(T a, T b) {
        return a.doubleValue() + b.doubleValue();
    }
}

class template

#include <iostream>
using namespace std;
// 通用模板
template <typename T>
class MyContainer {
public:
    MyContainer(T data) : data(data) {}
    void printData() {
        std::cout << "General template: " << data << std::endl;
    }
private:
    T data;
};

test class template

int main() {
    MyContainer<int> int_container(42);
    MyContainer<double> double_container(3.14);
    int int_data = int_container.printData(); // 编译器生成 int 特化版本
    double double_data = double_container.printData(); // 编译器生成 double 特化版本
}

func special template

template<typename T>
void print(T data) {
    std::cout << "General function template: " << data << std::endl;
}
template<>
void print<bool>(bool data) {
    std::cout << "Specialized function template for bool: " << (data ? "true" : "false") << std::endl;
}

class spcial template

template <>
class MyContainer<int> {
public:
    MyContainer(int data) : data(data) {}
    void printData() {
        std::cout << "Specialized template for int: " << data << std::endl;
    }
private:
    int data;
};

test class special template 1

int main() {
    MyContainer<int> int_container(42);
    int_container.printData(); // 输出:Specialized template for int: 42
    MyContainer<double> double_container(3.14);
    double_container.printData(); // 输出:General template: 3.14
    return 0;
}   

多个类型参数

与上述类似,只是类型参数扩展为多个,这里以两个为例

func template

template<typename T, typename K>
void printData(T& data1, K& data2) {
    std::cout << "Data 1: " << data1 << ", Data 2: " << data2 << std::endl;
}

class template

template<typename T, typename K>
class Pair {
public:
    Pair(const T& first, const K& second) : first_(first), second_(second) {}
    void print() const {
        std::cout << "First: " << first_ << ", Second: " << second_ << std::endl;
    }
private:
    T first_;
    K second_;
};

func special template

#include <iostream>
#include <string>
// 函数模板,接受两个不同类型的参数 T 和 K
template<typename T, typename K>
void printPair(const T& first, const K& second) {
    std::cout << "General template: First: " << first << ", Second: " << second << std::endl;
}
// 函数模板重载,针对 T 和 K 都是 std::string 的情况
void printPair(const std::string& first, const std::string& second) {
    std::cout << "Overloaded for std::string: First: " << first << ", Second: " << second << std::endl;
}
int main() {
    int intValue = 42;
    double doubleValue = 3.14;
    std::string stringValue1 = "Hello";
    std::string stringValue2 = "World!";

    // 使用函数模板,处理 int 和 double 类型参数
    printPair(intValue, doubleValue);
    // 使用函数模板,处理 int 和 std::string 类型参数
    printPair(intValue, stringValue1);
    // 使用重载的函数模板,处理 std::string 和 std::string 类型参数
    printPair(stringValue1, stringValue2);
    return 0;
}

class special template

#include <iostream>
template<typename T, typename K>
class Pair {
public:
    Pair(const T& first, const K& second) : first_(first), second_(second) {}
    void print() const {
        std::cout << "First: " << first_ << ", Second: " << second_ << std::endl;
    }
private:
    T first_;
    K second_;
};
// 特化 Pair 类模板,针对 T 为 int 和 K 为 std::string 的情况
template<>
class Pair<int, std::string> {
public:
    Pair(const int& first, const std::string& second) : first_(first), second_(second) {}
    void print() const {
        std::cout << "Specialized First: " << first_ << ", Specialized Second: " << second_ << std::endl;
    }
private:
    int first_;
    std::string second_;
};
int main() {
    int intValue = 42;
    double doubleValue = 3.14;
    std::string stringValue = "Hello, world!";
    // 使用类模板,创建一个 int 和 double 类型参数的对象
    Pair<int, double> intDoublePair(intValue, doubleValue);
    intDoublePair.print();
    // 使用特化的类模板,创建一个 int 和 std::string 类型参数的对象
    Pair<int, std::string> intStringPair(intValue, stringValue);
    intStringPair.print(); // 将调用特化的 print 函数
    // 使用类模板,创建一个 double 和 std::string 类型参数的对象
    Pair<double, std::string> doubleStringPair(doubleValue, stringValue);
    doubleStringPair.print();
    return 0;
}

特化模板

仅C++

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值