C++:泛型如何使用

在 C++ 中,泛型(或模板)是一种强大的编程机制,用于编写可以处理不同数据类型的通用代码。泛型通过模板实现,使得代码在编译时生成具体类型的实现。主要有两种类型的模板:函数模板类模板

函数模板

函数模板允许你定义一个函数模板,适用于多种数据类型。下面是一个简单的函数模板示例:

#include <iostream>

// 定义一个函数模板
template <typename T>
T max(T a, T b) {
    return (a > b) ? a : b;
}

int main() {
    std::cout << max(10, 20) << std::endl;      // 输出 20 (整数)
    std::cout << max(10.5, 20.5) << std::endl;  // 输出 20.5 (浮点数)
    return 0;
}

在这个示例中,template <typename T> 定义了一个模板类型参数 T。函数 max 可以处理任何支持比较操作的类型(如 intdouble)。

类模板

类模板允许你定义一个类模板,使其可以处理多种数据类型。下面是一个类模板的示例:

#include <iostream>

// 定义一个类模板
template <typename T>
class Stack {
private:
    std::vector<T> elements;
public:
    void push(const T& element) {
        elements.push_back(element);
    }
    
    T pop() {
        if (elements.empty()) {
            throw std::out_of_range("Stack<>::pop(): empty stack");
        }
        T elem = elements.back();
        elements.pop_back();
        return elem;
    }

    bool isEmpty() const {
        return elements.empty();
    }
};

int main() {
    // 使用 Stack<int>
    Stack<int> intStack;
    intStack.push(1);
    intStack.push(2);
    std::cout << intStack.pop() << std::endl;  // 输出 2

    // 使用 Stack<std::string>
    Stack<std::string> stringStack;
    stringStack.push("hello");
    stringStack.push("world");
    std::cout << stringStack.pop() << std::endl;  // 输出 "world"

    return 0;
}

在这个示例中,template <typename T> 定义了一个模板类型参数 TStack 类可以处理任何类型的元素。

模板特化

有时,你可能需要对特定的数据类型进行特殊处理。C++ 支持模板特化,可以为特定类型提供不同的实现:

函数模板特化

#include <iostream>

// 普通模板
template <typename T>
void print(T value) {
    std::cout << "General template: " << value << std::endl;
}

// 特化版本
template <>
void print(const char* value) {
    std::cout << "Specialized template for const char*: " << value << std::endl;
}

int main() {
    print(123);              // 调用一般模板
    print("Hello, World!"); // 调用特化模板
    return 0;
}

类模板特化

#include <iostream>

// 通用模板
template <typename T>
class Printer {
public:
    void print() {
        std::cout << "General template" << std::endl;
    }
};

// 特化版本
template <>
class Printer<int> {
public:
    void print() {
        std::cout << "Specialized template for int" << std::endl;
    }
};

int main() {
    Printer<double> p1;
    p1.print(); // 输出 "General template"

    Printer<int> p2;
    p2.print(); // 输出 "Specialized template for int"
    
    return 0;
}

总结

  • 函数模板:使得函数可以处理多种数据类型。
  • 类模板:允许类处理多种数据类型。
  • 模板特化:为特定类型提供专门的实现。

使用泛型(模板)可以编写高效、灵活的代码,减少重复,并提高代码的可重用性

其他注意事项

  • 模板参数类型:模板参数可以是任何类型,包括基本数据类型、用户定义的类、指针等。
  • 多个模板参数:类模板可以有多个模板参数,例如 template <typename T1, typename T2>
  • 默认模板参数:可以为模板参数提供默认值,例如 template <typename T = int>

多个模板参数和默认模板参数

// 类模板定义
template <typename T1, typename T2 = int>
class Pair {
private:
    T1 first;
    T2 second;
public:
    Pair(T1 f, T2 s) : first(f), second(s) {}
    void print() const {
        std::cout << "First: " << first << ", Second: " << second << std::endl;
    }
};

int main() {
    // 使用默认模板参数
    Pair<double> defaultPair(1.1, 2);  // T2 默认为 int
    defaultPair.print();              // 输出 "First: 1.1, Second: 2"

    // 指定所有模板参数
    Pair<double, std::string> customPair(1.1, "text");
    customPair.print();              // 输出 "First: 1.1, Second: text"

    return 0;
}

总之,在使用模板类时,指定模板参数是必须的,这样编译器才能为特定的类型生成正确的类实例。

  • 6
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值