template<typename T>使用

template<typename T> 是 C++ 中模板编程的核心语法,它表示定义一个类型模板参数 T。它的用法非常广泛,以下是主要的使用场景和模式:

1. 基本函数模板

cpp 复制代码
template<typename T>
T max(T a, T b) {
    return (a > b) ? a : b;
}

// 使用
int x = max(3, 5);        // T 推导为 int
double y = max(3.14, 2.7); // T 推导为 double

2. 基本类模板

cpp 复制代码
template<typename T>
class Box {
private:
    T content;
public:
    void set(const T& val) { content = val; }
    T get() const { return content; }
};

// 使用
Box<int> intBox;     // T = int
Box<string> strBox;  // T = string

3. 多个模板参数

cpp 复制代码
template<typename T, typename U>
class Pair {
    T first;
    U second;
public:
    Pair(const T& f, const U& s) : first(f), second(s) {}
};

Pair<int, string> p(1, "hello");

4. 模板特化

cpp 复制代码
// 主模板
template<typename T>
class Printer {
    void print(T val) { cout << val << endl; }
};

// 全特化(针对 bool 类型)
template<>
class Printer<bool> {
    void print(bool val) { cout << (val ? "true" : "false") << endl; }
};

5. 偏特化(部分特化)

cpp 复制代码
// 主模板
template<typename T, typename U>
class Container {};

// 偏特化:第二个参数固定为 int
template<typename T>
class Container<T, int> {};

// 偏特化:两个指针类型
template<typename T, typename U>
class Container<T*, U*> {};

6. 模板模板参数

cpp 复制代码
template<typename T, template<typename> class Container>
class MyClass {
    Container<T> data;
};

// 使用
MyClass<int, vector> obj;

7. 非类型模板参数配合

cpp 复制代码
template<typename T, int Size>
class Array {
    T elements[Size];
public:
    int size() const { return Size; }
};

Array<int, 10> arr;  // 10 是编译期常量

8. 成员模板

cpp 复制代码
template<typename T>
class MyClass {
public:
    template<typename U>
    void genericMethod(const U& param) {
        // 使用 T 和 U
    }
    
    template<typename U>
    MyClass(const U& val) {
        // 转换构造函数模板
    }
};

9. 模板别名

cpp 复制代码
template<typename T>
using Vec = std::vector<T>;

Vec<int> v;  // 等价于 std::vector<int>

// 更复杂的例子
template<typename T, typename U>
using Map = std::map<T, U>;

template<typename T>
using StringMap = Map<string, T>;

10. 可变参数模板(C++11)

cpp 复制代码
// 递归方式
template<typename T>
T sum(T val) { return val; }

template<typename T, typename... Args>
T sum(T first, Args... args) {
    return first + sum(args...);
}

// 折叠表达式(C++17)
template<typename... Args>
auto sum(Args... args) {
    return (args + ...);  // 二元左折叠
}

// 使用
int result = sum(1, 2, 3, 4);  // 10

11. 返回类型推导

cpp 复制代码
// C++14 自动推导返回类型
template<typename T, typename U>
auto add(T a, U b) {
    return a + b;
}

// 使用尾置返回类型(C++11)
template<typename T, typename U>
auto multiply(T a, U b) -> decltype(a * b) {
    return a * b;
}

12. SFINAE 应用

cpp 复制代码
// 只为整数类型启用
template<typename T>
typename std::enable_if<std::is_integral<T>::value, T>::type
process(T val) {
    return val * 2;
}

// 只为浮点类型启用
template<typename T>
typename std::enable_if<std::is_floating_point<T>::value, T>::type
process(T val) {
    return val * 2.0;
}

13. 依赖类型(typename 关键字的另一个用法)

cpp 复制代码
template<typename T>
class Example {
    // 需要 typename 告诉编译器这是一个类型,不是静态成员
    typename T::iterator it;
    
    // 如果不加 typename,会编译错误
    // T::iterator it;  // 错误
};

关键要点:

  • typename 和 class 在模板参数中完全等价 (template<class T> 也可以)
  • 模板参数在编译期实例化,生成具体代码
  • 模板定义通常放在头文件中(不能分离编译)
  • C++20 引入了概念(concepts)来约束模板参数

这些用法使 C++ 能够实现泛型编程,编写与类型无关的代码,同时保持类型安全和高性能。

相关推荐
希和202713 分钟前
C语言程序设计题|有序数组插入数字冒泡排序
c语言·数据结构·算法
老秦包你会21 分钟前
计算机网络第二课 ----Socket(套接字)编程预备
开发语言·计算机网络·php
旖旎夜光23 分钟前
【C++ 基础入门】C++多态(下):单/多继承虚表、多态补充与 21 道高频题
开发语言·c++·笔记·学习
Pniubi28 分钟前
力扣73 矩阵置零
算法·leetcode·矩阵
天天被压力32 分钟前
【A股分钟级高频数据完全手册 #11】券商实时行情数据接口:实时交易(券商源)接入与字段
java·人工智能·python
天天被压力1 小时前
【A股分钟级高频数据完全手册 #12】股票五档盘口数据接口:买卖五档实时盘口解析
java·人工智能·python
Wang's Blog10 小时前
Java 项目实战: 交友项目 - FastDFS:入门案例
java·开发语言·交友
apcipot_rain11 小时前
C++转Java日记(03)
java·开发语言·c++
皮皮林55111 小时前
Java实现微信扫码登录
java
布莱克60511 小时前
C++ 中 map 的 insert 与 emplace:key 已存在时会覆盖吗?
开发语言·数据结构·c++·算法·map