泛型编程

C++ 中的泛型编程和模板技术

generic-programming.cpp

#include <iostream>
#include <vector>
#include <string>
#include <type_traits>
#include <concepts>
#include <memory>
#include <algorithm>
#include <tuple>
#include <variant>
#include <optional>

// 1. 基础函数模板
template<typename T>
T maximum(T a, T b) {
    return (a > b) ? a : b;
}

// 2. 多参数模板
template<typename T, typename U>
auto add(T a, U b) -> decltype(a + b) {
    return a + b;
}

// 3. 类模板
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::runtime_error("Stack is empty");
        }
        T element = elements.back();
        elements.pop_back();
        return element;
    }
    
    bool empty() const {
        return elements.empty();
    }
    
    size_t size() const {
        return elements.size();
    }
    
    void print() const {
        std::cout << "Stack: [";
        for (size_t i = 0; i < elements.size(); ++i) {
            std::cout << elements[i];
            if (i < elements.size() - 1) std::cout << ", ";
        }
        std::cout << "]";
    }
};

// 4. 模板特化
template<typename T>
class TypeInfo {
public:
    static void print() {
        std::cout << "Unknown type";
    }
};

// 特化版本
template<>
class TypeInfo<int> {
public:
    static void print() {
        std::cout << "Integer type";
    }
};

template<>
class TypeInfo<std::string> {
public:
    static void print() {
        std::cout << "String type";
    }
};

// 5. 偏特化
template<typename T, typename U>
class Pair {
public:
    T first;
    U second;
    
    Pair(T f, U s) : first(f), second(s) {}
    
    void print() const {
        std::cout << "(" << first << ", " << second << ")";
    }
};

// 偏特化:当两个类型相同时
template<typename T>
class Pair<T, T> {
public:
    T first;
    T second;
    
    Pair(T f, T s) : first(f), second(s) {}
    
    void print() const {
        std::cout << "Same type pair: (" << first << ", " << second << ")";
    }
    
    T sum() const {
        return first + second;
    }
};

// 6. 变参模板 (C++11)
template<typename... Args>
void printAll(Args... args) {
    ((std::cout << args << " "), ...);
    std::cout << std::endl;
}

// 7. 折叠表达式 (C++17)
template<typename... Args>
auto sumAll(Args... args) {
    return (args + ...);
}

template<typename... Args>
auto multiplyAll(Args... args) {
    return (args * ...);
}

// 8. SFINAE (Substitution Failure Is Not An Error)
template<typename T>
typename std::enable_if<std::is_integral<T>::value, T>::type
processNumber(T value) {
    return value * 2;
}

template<typename T>
typename std::enable_if<std::is_floating_point<T>::value, T>::type
processNumber(T value) {
    return value * 1.5;
}

// 9. 概念 (C++20)
template<typename T>
concept Numeric = std::integral<T> || std::floating_point<T>;

template<Numeric T>
T square(T value) {
    return value * value;
}

template<typename T>
concept Printable = requires(T t) {
    std::cout << t;
};

template<Printable T>
void printValue(T value) {
    std::cout << "Value: " << value << std::endl;
}

// 10. 模板元编程
template<int N>
struct Factorial {
    static const int value = N * Factorial<N - 1>::value;
};

template<>
struct Factorial<0> {
    static const int value = 1;
};

// 11. 类型萃取
template<typename T>
void printTypeInfo() {
    std::cout << "Type: " << typeid(T).name() << std::endl;
    std::cout << "Size: " << sizeof(T) << " bytes" << std::endl;
    std::cout << "Is integral: " << std::is_integral_v<T> << std::endl;
    std::cout << "Is pointer: " << std::is_pointer_v<T> << std::endl;
    std::cout << "Is class: " << std::is_class_v<T> << std::endl;
}

// 12. 完美转发
template<typename T>
void process(T&& value) {
    std::cout << "Processing: " << value << std::endl;
}

template<typename T>
void forwardValue(T&& value) {
    process(std::forward<T>(value));
}

// 13. 模板别名
template<typename T>
using Vector = std::vector<T>;

template<typename T>
using Optional = std::optional<T>;

// 14. 变参模板类
template<typename... Types>
class Tuple {
private:
    std::tuple<Types...> data;
    
public:
    Tuple(Types... args) : data(args...) {}
    
    template<size_t Index>
    auto get() -> decltype(std::get<Index>(data)) {
        return std::get<Index>(data);
    }
    
    void print() const {
        std::cout << "Tuple with " << sizeof...(Types) << " elements";
    }
};

// 15. 模板约束
template<typename T>
requires std::equality_comparable<T>
bool areEqual(const T& a, const T& b) {
    return a == b;
}

// 16. 模板特化与重载
template<typename T>
void processValue(T value) {
    std::cout << "Generic process: " << value << std::endl;
}

template<>
void processValue<int>(int value) {
    std::cout << "Integer process: " << value << " (doubled: " << value * 2 << ")" << std::endl;
}

template<>
void processValue<std::string>(std::string value) {
    std::cout << "String process: \"" << value << "\" (length: " << value.length() << ")" << std::endl;
}

// 17. 模板递归
template<typename T, size_t N>
class Array {
private:
    T data[N];
    
public:
    T& operator[](size_t index) { return data[index]; }
    const T& operator[](size_t index) const { return data[index]; }
    
    size_t size() const { return N; }
    
    void fill(const T& value) {
        std::fill(data, data + N, value);
    }
    
    void print() const {
        std::cout << "[";
        for (size_t i = 0; i < N; ++i) {
            std::cout << data[i];
            if (i < N - 1) std::cout << ", ";
        }
        std::cout << "]";
    }
};

// 18. 模板友元
template<typename T>
class Container {
private:
    T data;
    
public:
    Container(T value) : data(value) {}
    
    template<typename U>
    friend class Container;
    
    template<typename U>
    void copyFrom(const Container<U>& other) {
        data = static_cast<T>(other.data);
    }
    
    void print() const {
        std::cout << "Container: " << data << std::endl;
    }
};

int main() {
    std::cout << "=== C++ 泛型编程示例 ===" << std::endl;
    
    // 1. 基础函数模板
    std::cout << "\n--- 基础函数模板 ---" << std::endl;
    std::cout << "maximum(10, 20) = " << maximum(10, 20) << std::endl;
    std::cout << "maximum(3.14, 2.71) = " << maximum(3.14, 2.71) << std::endl;
    std::cout << "maximum('a', 'z') = " << maximum('a', 'z') << std::endl;
    
    // 2. 多参数模板
    std::cout << "\n--- 多参数模板 ---" << std::endl;
    std::cout << "add(10, 3.14) = " << add(10, 3.14) << std::endl;
    std::cout << "add(3.14, 10) = " << add(3.14, 10) << std::endl;
    
    // 3. 类模板
    std::cout << "\n--- 类模板 ---" << std::endl;
    Stack<int> intStack;
    intStack.push(1);
    intStack.push(2);
    intStack.push(3);
    intStack.print();
    std::cout << std::endl;
    std::cout << "Popped: " << intStack.pop() << std::endl;
    intStack.print();
    std::cout << std::endl;
    
    Stack<std::string> stringStack;
    stringStack.push("Hello");
    stringStack.push("World");
    stringStack.print();
    std::cout << std::endl;
    
    // 4. 模板特化
    std::cout << "\n--- 模板特化 ---" << std::endl;
    TypeInfo<int>::print();
    std::cout << std::endl;
    TypeInfo<std::string>::print();
    std::cout << std::endl;
    TypeInfo<double>::print();
    std::cout << std::endl;
    
    // 5. 偏特化
    std::cout << "\n--- 偏特化 ---" << std::endl;
    Pair<int, std::string> pair1(1, "Hello");
    pair1.print();
    std::cout << std::endl;
    
    Pair<int, int> pair2(5, 10);
    pair2.print();
    std::cout << " Sum: " << pair2.sum() << std::endl;
    
    // 6. 变参模板
    std::cout << "\n--- 变参模板 ---" << std::endl;
    printAll(1, 2, 3, "Hello", 3.14);
    printAll("One", "Two", "Three");
    
    // 7. 折叠表达式
    std::cout << "\n--- 折叠表达式 ---" << std::endl;
    std::cout << "sumAll(1, 2, 3, 4, 5) = " << sumAll(1, 2, 3, 4, 5) << std::endl;
    std::cout << "multiplyAll(2, 3, 4) = " << multiplyAll(2, 3, 4) << std::endl;
    
    // 8. SFINAE
    std::cout << "\n--- SFINAE ---" << std::endl;
    std::cout << "processNumber(10) = " << processNumber(10) << std::endl;
    std::cout << "processNumber(3.14) = " << processNumber(3.14) << std::endl;
    
    // 9. 概念 (C++20)
    std::cout << "\n--- 概念 ---" << std::endl;
    std::cout << "square(5) = " << square(5) << std::endl;
    std::cout << "square(3.14) = " << square(3.14) << std::endl;
    printValue(42);
    printValue("Hello");
    
    // 10. 模板元编程
    std::cout << "\n--- 模板元编程 ---" << std::endl;
    std::cout << "Factorial<5>::value = " << Factorial<5>::value << std::endl;
    std::cout << "Factorial<10>::value = " << Factorial<10>::value << std::endl;
    
    // 11. 类型萃取
    std::cout << "\n--- 类型萃取 ---" << std::endl;
    std::cout << "int 类型信息:" << std::endl;
    printTypeInfo<int>();
    std::cout << "double 类型信息:" << std::endl;
    printTypeInfo<double>();
    
    // 12. 完美转发
    std::cout << "\n--- 完美转发 ---" << std::endl;
    forwardValue(42);
    forwardValue(std::string("Hello"));
    
    // 13. 模板别名
    std::cout << "\n--- 模板别名 ---" << std::endl;
    Vector<int> vec = {1, 2, 3, 4, 5};
    std::cout << "Vector size: " << vec.size() << std::endl;
    
    Optional<int> opt = 42;
    if (opt) {
        std::cout << "Optional value: " << *opt << std::endl;
    }
    
    // 14. 变参模板类
    std::cout << "\n--- 变参模板类 ---" << std::endl;
    Tuple<int, std::string, double> tuple(42, "Hello", 3.14);
    tuple.print();
    std::cout << std::endl;
    std::cout << "First element: " << tuple.get<0>() << std::endl;
    
    // 15. 模板约束
    std::cout << "\n--- 模板约束 ---" << std::endl;
    std::cout << "areEqual(5, 5) = " << areEqual(5, 5) << std::endl;
    std::cout << "areEqual(5, 6) = " << areEqual(5, 6) << std::endl;
    
    // 16. 模板特化与重载
    std::cout << "\n--- 模板特化与重载 ---" << std::endl;
    processValue(42);
    processValue(std::string("Hello"));
    processValue(3.14);
    
    // 17. 模板递归
    std::cout << "\n--- 模板递归 ---" << std::endl;
    Array<int, 5> arr;
    arr.fill(10);
    arr.print();
    std::cout << std::endl;
    
    // 18. 模板友元
    std::cout << "\n--- 模板友元 ---" << std::endl;
    Container<int> container1(42);
    Container<double> container2(3.14);
    container1.print();
    container2.print();
    container2.copyFrom(container1);
    container2.print();
    
    std::cout << "\n泛型编程示例完成!" << std::endl;
    
    return 0;
}

Run Result

$ g++ -std=c++23 generic-programming.cpp -o generic-programming
$ ./generic-programming
=== C++ 泛型编程示例 ===

--- 基础函数模板 ---
maximum(10, 20) = 20
maximum(3.14, 2.71) = 3.14
maximum('a', 'z') = z

--- 多参数模板 ---
add(10, 3.14) = 13.14
add(3.14, 10) = 13.14

--- 类模板 ---
Animal Buddy created
Dog Buddy of breed Golden Retriever created
Stack: [1, 2, 3]
Popped: 3
Stack: [1, 2]
Animal Hello created
Stack: [Hello, World]

--- 模板特化 ---
Integer type
String type
Unknown type

--- 偏特化 ---
(1, Hello)
Same type pair: (5, 10) Sum: 15

--- 变参模板 ---
1 2 3 Hello 3.14 
One Two Three 

--- 折叠表达式 ---
sumAll(1, 2, 3, 4, 5) = 15
multiplyAll(2, 3, 4) = 24

--- SFINAE ---
processNumber(10) = 20
processNumber(3.14) = 4.71

--- 概念 ---
square(5) = 25
square(3.14) = 9.8596
Value: 42
Value: Hello

--- 模板元编程 ---
Factorial<5>::value = 120
Factorial<10>::value = 3628800

--- 类型萃取 ---
int 类型信息:
Type: i
Size: 4 bytes
Is integral: 1
Is pointer: 0
Is class: 0
double 类型信息:
Type: d
Size: 8 bytes
Is integral: 0
Is pointer: 0
Is class: 0

--- 完美转发 ---
Processing: 42
Processing: Hello

--- 模板别名 ---
Vector size: 5
Optional value: 42

--- 变参模板类 ---
Tuple with 3 elements
First element: 42

--- 模板约束 ---
areEqual(5, 5) = 1
areEqual(5, 6) = 0

--- 模板特化与重载 ---
Integer process: 42 (doubled: 84)
String process: "Hello" (length: 5)
Generic process: 3.14

--- 模板递归 ---
[10, 10, 10, 10, 10]

--- 模板友元 ---
Container: 42
Container: 3.14
Container: 42

泛型编程示例完成!

Code Explanation

  • 函数模板 - 可以处理多种类型的通用函数
  • 类模板 - 可以处理多种类型的通用类
  • 模板特化 - 为特定类型提供特殊实现
  • 偏特化 - 为部分模板参数提供特殊实现
  • 变参模板 - 接受可变数量参数的模板
  • 折叠表达式 - C++17 的简洁语法处理参数包
  • SFINAE - 替换失败不是错误,用于模板元编程
  • 概念 - C++20 的模板约束机制
  • 模板元编程 - 在编译时进行计算
  • 类型萃取 - 在编译时获取类型信息
  • 完美转发 - 保持参数的值类别
  • 模板别名 - 为复杂类型创建简洁的别名