位置: 文档库 > C/C++ > C++模板基础 函数模板类模板语法

C++模板基础 函数模板类模板语法

FrostScribe 上传于 2024-06-27 18:20

### C++模板基础:函数模板与类模板语法详解

C++模板是泛型编程的核心机制,允许开发者编写与类型无关的代码。通过模板,可以避免为不同数据类型重复编写相似逻辑,显著提升代码复用性和可维护性。本文将系统讲解函数模板和类模板的语法规则、使用场景及高级特性,帮助读者掌握这一强大的编程工具。

一、函数模板基础语法

函数模板通过定义通用函数原型,支持在编译时根据调用参数自动生成特定类型的函数实例。

1.1 基本语法结构

template   // 或 class T
T max(T a, T b) {
    return (a > b) ? a : b;
}

模板声明以`template`关键字开头,后跟模板参数列表。`typename`或`class`关键字用于声明类型参数(二者在此场景下等价)。函数体中使用模板参数`T`作为占位类型。

1.2 模板实例化

调用模板函数时,编译器根据实参类型推导模板参数:

int a = 5, b = 10;
cout 

也可显式指定类型:

double x = 3.14, y = 2.71;
cout (x, y);  // 显式实例化为 double 版本

1.3 多参数模板

模板可支持多个类型参数:

template 
void printPair(T1 first, T2 second) {
    cout 

1.4 非类型模板参数

模板参数可以是值而非类型:

template 
T arraySum(T arr[]) {
    T sum = T();  // 默认构造
    for (int i = 0; i (nums);  // 输出6
}

二、类模板基础语法

类模板允许定义与类型无关的类结构,常见于容器类(如`std::vector`)的实现。

2.1 基本类模板定义

template 
class Stack {
private:
    vector elements;
public:
    void push(const T& element) {
        elements.push_back(element);
    }
    T pop() {
        if (elements.empty()) throw out_of_range("Stack empty");
        T element = elements.back();
        elements.pop_back();
        return element;
    }
};

2.2 类模板实例化

Stack intStack;
intStack.push(42);
cout  strStack;
strStack.push("Hello");
cout 

2.3 模板类成员函数定义

成员函数可在类外定义,需重复模板参数:

template 
class Box {
public:
    T content;
    void print();
};

template 
void Box::print() {
    cout 

2.4 模板特化

可为特定类型提供专门实现:

// 全特化
template 
class Stack {
    // 针对bool类型的优化实现
};

// 偏特化(针对指针类型)
template 
class Stack {
    // 针对指针类型的实现
};

三、模板高级特性

3.1 默认模板参数

template 
class DefaultType {
    T value;
public:
    DefaultType(T v) : value(v) {}
    T getValue() const { return value; }
};

DefaultType dt(10);  // 使用int作为默认类型

3.2 可变参数模板(C++11起)

// 打印任意数量和类型的参数
template 
void printAll(Args... args) {
    ((cout 

3.3 模板元编程基础

通过模板实现编译期计算:

template 
struct Factorial {
    static const int value = N * Factorial::value;
};

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

cout ::value;  // 输出120

四、模板使用最佳实践

4.1 头文件与实现分离

类模板成员函数通常需在头文件中实现,或使用显式实例化:

// stack.h
template 
class Stack { /*...*/ };

// stack.cpp
template class Stack;  // 显式实例化int版本

4.2 模板参数命名约定

常用命名规范:

  • `T`:通用类型
  • `Iter`:迭代器类型
  • `Key`, `Value`:键值对类型

4.3 避免代码膨胀

显式实例化可减少生成的代码量:

// 在.cpp文件中
template class std::vector;  // 仅生成bool版本的vector

五、常见问题与解决方案

5.1 模板参数推导失败

问题示例:

template 
void process(T& param) {}

const int x = 10;
process(x);  // 推导为int&,无法绑定到const int

解决方案:使用`const T&`或通用引用。

5.2 模板依赖名称问题

问题示例:

template 
void foo() {
    T::innerType* ptr;  // 被解析为乘法而非类型声明
}

解决方案:使用`typename`关键字:

template 
void foo() {
    typename T::innerType* ptr;
}

5.3 模板递归深度限制

编译期递归可能受编译器限制,可通过迭代替代或增加限制:

#pragma GCC diagnostic ignored "-Wtemplate-recursion-depth"

六、现代C++中的模板演进

6.1 C++17的模板改进

  • 类模板参数推导(CTAD):
template 
struct Pair {
    T first;
    T second;
};

Pair p{1, 2};  // 自动推导为Pair

6.2 C++20的概念(Concepts)

约束模板参数:

template 
concept Integral = std::is_integral_v;

template 
T add(T a, T b) { return a + b; }  // 仅接受整数类型

6.3 非类型模板参数扩展

C++20允许使用浮点数和类类型作为非类型参数:

struct Point { int x, y; };

template 
class Location {};

关键词:C++模板、函数模板、类模板、模板特化、可变参数模板、模板元编程概念约束编译期推导

简介:本文全面解析C++模板编程的核心机制,涵盖函数模板与类模板的基础语法、多参数模板、非类型参数、模板特化等关键特性,并深入探讨可变参数模板、模板元编程等高级技术。结合现代C++标准(C++17/C++20)的新特性,如类模板参数推导和概念约束,提供从基础到进阶的完整知识体系,帮助开发者高效利用模板实现泛型编程。

《C++模板基础 函数模板类模板语法.doc》
将本文的Word文档下载到电脑,方便收藏和打印
推荐度:
点击下载文档