目录

FX-模板

FX-模板

C++ 模板是 C++ 中实现泛型编程的重要工具。通过模板,你可以编写与类型无关的代码,从而提高代码的复用性和灵活性。以下是 C++ 模板的一些关键概念和用法:

1. 函数模板

函数模板允许你编写一个通用的函数,可以处理不同类型的参数。

template <typename T>
T add(T a, T b) {
    return a + b;
}

int main() {
    int i = add(1, 2);       // T 被推导为 int
    double d = add(1.5, 2.5); // T 被推导为 double
    return 0;
}

2. 类模板

类模板允许你定义一个通用的类,可以处理不同类型的数据成员。

template <typename T>
class Box {
private:
    T value;
public:
    Box(T v) : value(v) {}
    T getValue() const { return value; }
};

int main() {
    Box<int> intBox(123);
    Box<std::string> strBox("Hello");
    return 0;
}

3. 模板特化

模板特化允许你为特定类型提供特殊的实现。

template <typename T>
class Box {
public:
    void print() {
        std::cout << "Generic Box" << std::endl;
    }
};

template <>
class Box<int> {
public:
    void print() {
        std::cout << "Specialized Box for int" << std::endl;
    }
};

int main() {
    Box<double> dBox;
    dBox.print(); // 输出: Generic Box

    Box<int> iBox;
    iBox.print(); // 输出: Specialized Box for int
    return 0;
}

4. 非类型模板参数

模板参数不仅可以是类型,还可以是常量表达式。

template <typename T, int size>
class Array {
private:
    T arr[size];
public:
    T& operator[](int index) {
        return arr[index];
    }
};

int main() {
    Array<int, 5> intArray;
    intArray[0] = 10;
    return 0;
}

5. 可变参数模板

可变参数模板允许你编写接受任意数量参数的模板。

template <typename... Args>
void print(Args... args) {
    (std::cout << ... << args) << std::endl;
}

int main() {
    print(1, 2, 3, "Hello", 4.5); // 输出: 1 2 3 Hello 4.5
    return 0;
}

6. 模板元编程

模板元编程是一种在编译时进行计算的技术,通常用于生成高效的代码。

template <int N>
struct Factorial {
    static const int value = N * Factorial<N - 1>::value;
};

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

int main() {
    std::cout << Factorial<5>::value << std::endl; // 输出: 120
    return 0;
}

7. 模板别名

使用 using 关键字可以为模板定义别名,简化代码。

template <typename T>
using Vec = std::vector<T>;

int main() {
    Vec<int> v = {1, 2, 3};
    return 0;
}

8. 模板的默认参数

模板参数可以有默认值。

template <typename T = int>
class Box {
private:
    T value;
public:
    Box(T v) : value(v) {}
    T getValue() const { return value; }
};

int main() {
    Box<> defaultBox(123); // 使用默认类型 int
    Box<double> doubleBox(123.45);
    return 0;
}

9. 模板的 SFINAE (Substitution Failure Is Not An Error)

SFINAE 是一种模板技术,用于在模板实例化过程中排除不符合条件的重载。

template <typename T>
typename std::enable_if<std::is_integral<T>::value, T>::type
add(T a, T b) {
    return a + b;
}

int main() {
    auto result = add(1, 2); // 正常编译
    // auto result2 = add(1.5, 2.5); // 编译错误,因为 double 不是整数类型
    return 0;
}

10. 模板的约束 (C++20 Concepts)

C++20 引入了 Concepts,用于对模板参数进行约束。

#include <concepts>

template <std::integral T>
T add(T a, T b) {
    return a + b;
}

int main() {
    auto result = add(1, 2); // 正常编译
    // auto result2 = add(1.5, 2.5); // 编译错误,因为 double 不满足 std::integral
    return 0;
}

总结

C++ 模板是强大的工具,能够极大地提高代码的复用性和灵活性。通过掌握函数模板、类模板、模板特化、可变参数模板等概念,你可以编写出更加通用和高效的代码。C++20 的 Concepts 进一步增强了模板的表达能力,使得模板编程更加直观和安全。