Skip to content

模版

约 627 个字 78 行代码 预计阅读时间 3 分钟

简介

C++模板是C++编程语言中的一种强大工具,允许你编写与类型无关的代码。模板分为两种主要类型:函数模板和类模板。

编写泛型代码的两个重要原则: * 模版中的函数参数是const引用:保证函数可以用于不能拷贝的类型 * 函数体中的条件判断仅使用 < 比较:降低函数对处理类型的要求,只需要支持<,不一定要支持>

1. 函数模板

函数模板允许你创建一个函数模板,这个模板可以处理多种数据类型。其基本形式如下:

template <typename T>
T max(T a, T b) {
    return (a > b) ? a : b;
}

使用时,你可以传递不同类型的参数:

int main() {
    cout << max(10, 5) << endl;        // int 类型
    cout << max(10.5, 5.5) << endl;    // double 类型
    return 0;
}

2. 类模板

类模板允许你创建一个类模板,该模板可以处理不同的数据类型。基本形式如下:

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 empty() const {
        return elements.empty();
    }
};

使用时,你可以指定模板参数:

int main() {
    Stack<int> intStack;
    intStack.push(1);
    intStack.push(2);
    cout << intStack.pop() << endl;

    Stack<std::string> stringStack;
    stringStack.push("hello");
    stringStack.push("world");
    cout << stringStack.pop() << endl;

    return 0;
}

3. 模板的特化

有时你可能需要对模板的特定类型进行特化,以便提供专门的实现。例如,特化Stack类模板以处理bool类型:

template <>
class Stack<bool> {
private:
    std::vector<bool> elements;
public:
    void push(bool element) {
        elements.push_back(element);
    }
    bool pop() {
        if (elements.empty()) throw std::out_of_range("Stack<bool>::pop(): empty stack");
        bool elem = elements.back();
        elements.pop_back();
        return elem;
    }
    bool empty() const {
        return elements.empty();
    }
};

标准模版库

顺序容器

Name Function
vector 可变大小的数组
deque 双端队列
list 双向链表
forward_list 单向链表
array 固定大小数组
string 字符串

除了固定大小的数组,其它容器都提供高效、灵活的内存管理。没有特殊考虑一般情况选vector。容器的元素类型可以是另一种容器。

顺序容器迭代器

auto begin = con.begin();
auto end = con.end();
while(begin != end)
{
    *begin = val;
    ++begin;
}
迭代器有多个版本: * begin 正向迭代器 * rbegin 反向迭代器 * cbegin const迭代器 * crbegin const反向迭代器

泛型算法

find(begin,end,val);
find_if(begin,end,predict);
accumulate(begin,end,0);
equal(begin1,end1,begin2);
fill(begin,end,val);
fill_n(begin,size,value);
copy(begin(a1),end(a1),a2);
replace(begin,end,origin value,goal value);
replace_copy(begin,end,back_inserter(v),val1,val2)
sort(begin,end);
unique(begin,end);

关联容器

Name Function
按关键字有序保存元素
map 关联数组:保存关键字-值对
set 关键字即值,即只保存关键字的容器
multimap 关键字可重复出现的map
multiset 关键字可重复出现的set
无序集合
unordered_map 用哈希函数组织的map
unordered_set 用哈希函数组织的set
unordered_multiamp 哈希函数组织的map;关键字可重复出现
unordered_multiset 哈希函数组织的set;关键字可以重复出现

Pair

定义在头文件utility中 与其他标准库的类型不同,pair的数据成员是public的,所以可以直接

p.first;
p.second;

关联容器迭代器

当解引用一个关联容器迭代器时,我们会得到一个类型为容器的value_type的值引用。 当使用一个迭代器遍历关联容器时,迭代器按关键字升序排列元素