C++ STL 概述

什么是 STL

STL ( The C++ Standard Template Library ),C++标准模板库,是一个算法、数据结构和其他组件的集合,可用于简化C++程序的开发。STL提供了一系列的 容器 (container),如 vector、list、map,以及搜索、排序和操作数据的 算法 (algorithm)。

STL的主要优点之一是它提供了一种编写通用的、可重复使用的代码的方法,可以应用于不同的数据类型。这意味着,你可以一次写好一个算法,然后将其用于不同类型的数据,而不必为每种类型单独写代码。

STL 的组成

  1. 容器 (Container): STL 提供了一系列的容器,如 vector、list、map、set 和 stack 等,它们可以用来存储和操作数据。
  2. 算法 (Algorithm): STL 提供了一系列的算法,比如 sort、find 和 binary_search,这些算法可以用来操作存储在容器中的数据。
  3. 迭代器(Iterator): 迭代器是提供遍历容器中元素的方法的对象。STL提供了一系列的迭代器,比如前向迭代器 (forward iterator)、双向迭代器 (bidirectional iterator) 和随机访问迭代器 (random access iterator),它们可以与不同类型的容器一起使用。
  4. 函数对象(Function objects): 函数对象,也被称为functors,是可以作为算法的函数参数使用的对象。它们提供了一种将函数传递给算法的方法,允许你自定义其行为。
  5. 分配器(Allocator):分配器是一种用于管理内存分配和释放的工具。
  6. 适配器(Adapter):适配器是一种用于在现有的容器或迭代器(或上面其他组件,没有算法适配器)上添加新功能的工具,其本质还是容器和迭代器。

迭代器

常用的迭代器包括:输入迭代器(Input Iterator)、输出迭代器(Output Iterator)、前向迭代器(Forward Iterator)、双向迭代器(Bidirectional Iterator)、随机访问迭代器(Random Access Iterator)5种。输入迭代器和输出迭代器,它们不是把数组或容器当做操作对象,而是把输入流/输出流作为操作对象。这里简单介绍后面3种迭代器。

  • 前向迭代器

前向迭代器支持以下运算:

运算 说明
* 解引用,得到迭代器指向元素的值
++it 前置递增,将迭代器指向下一个元素
it++ 后置递增,将迭代器指向下一个元素,并返回指向当前元素的迭代器副本
==,!= 比较两个迭代器是否相等
  • 双向迭代器

双向迭代器支持以下运算:

运算 说明
* 解引用,得到迭代器指向元素的值
++it 前置递增,将迭代器指向下一个元素
it++ 后置递增,将迭代器指向下一个元素,并返回指向当前元素的迭代器副本
–it 前置递减,将迭代器指向前一个元素
it– 后置递减,将迭代器指向前一个元素,并返回指向当前元素的迭代器副本
==,!= 比较两个迭代器是否相等
  • 随机访问迭代器

随机访问迭代器则支持更多的运算:

运算 说明
* 解引用,得到迭代器指向元素的值
++it 前置递增,将迭代器指向下一个元素
it++ 后置递增,将迭代器指向下一个元素,并返回指向当前元素的迭代器副本
–it 前置递减,将迭代器指向前一个元素
it– 后置递减,将迭代器指向前一个元素,并返回指向当前元素的迭代器副本
==、!=、<、<=、>、>= 关系运算,用于比较两个迭代器的大小关系
it + n 加法,用于将迭代器向前移动 n 个元素
it1 - it2 和 it - n 减法,用于计算两个迭代器之间的距离,或将迭代器向后移动 n 个元素
it [ n ] 返回指向 it 后面第 n 个位置的元素的引用
  • 实现一个简单的迭代器:
template <typename T>
class ArrayIterator {
public:
    ArrayIterator(T* ptr) : ptr_(ptr) {}
    T& operator*() const {
        return *ptr_;
    }
    T* operator->() const {
        return ptr_;
    }
    ArrayIterator& operator++() {
        ++ptr_;
        return *this;
    }
    ArrayIterator& operator--() {
        --ptr_;
        return *this;
    }
private:
    T* ptr_;
};

int main() {
    int my_array[] = {1, 2, 3, 4, 5};
    ArrayIterator<int> it(my_array); // 创建一个迭代器
    for (; it != ArrayIterator<int>(my_array + 5); ++it) {
        std::cout << *it << " "; // 输出数组元素
    }
    return 0;
}

常用容器

容器类型 说明
序列式容器(Sequence containers) 这种容器按照元素在容器中的位置存储元素,可以按照索引访问元素。包括 vectordequelistforward_listarray
关联式容器(Associative containers) 这种容器按照元素的键值存储元素,可以按照键值进行查找和访问元素,查找效率高。包括 setmapmultisetmultimap
无序关联式容器(Unordered associative containers) 这种容器也是按照元素的键值存储元素,但是它们使用哈希表来存储元素,因此它们不保证元素的顺序,另外容器的查找效率高。包括 unordered_setunordered_mapunordered_multisetunordered_multimap
容器适配器(Container adapters) 这种容器是对其他容器的封装,提供了不同的接口。包括 stackqueuepriority_queue
  • 不同容器支持的迭代器不一样,主要是和容器的功能有关:
容器 对应的迭代器类型
array 随机访问迭代器
vector 随机访问迭代器
deque 随机访问迭代器
list 双向迭代器
set / multiset 双向迭代器
map / multimap 双向迭代器
forward_list 前向迭代器
unordered_map / unordered_multimap 前向迭代器
unordered_set / unordered_multiset 前向迭代器

其中,容器适配器因为其只是用于完成特殊的功能(先进先出 FIFO,后进先出LIFO)而不使用迭代器。在每个容器中,可以使用成员函数 begin( ) 获取对应的迭代器。

算法

STL 实现了数据结构与算法的分离,不需要在每个容器中单独地实现排序,查找什么的算法。通过迭代器可以将算法运用在不同的容器中,这也是迭代器的重要作用之一。这些算法也适用于普通数组。

#include <algorithm>
#include <iostream>

int main() {
    int my_array[] = {5, 2, 1, 7, 4};
    std::sort(my_array, my_array + 5);//默认升序
    for (int i = 0; i < 5; ++i) {
        std::cout << my_array[i] << " ";
    }
    return 0;
}

函数对象

简单来说就是实现了 ( ) 运算符重载的类,这个类的实例对象就是一个函数对象。在使用这个对象时看上去像函数调用,而实际也执行了函数调用,所以叫做函数对象。

template<typename T>
class plus{
public:
    T operator()(const T a, const T b){
        return a+b;
    }
};
int main() {
    plus<int> a;
    std::cout << a(1,2) <<std::endl; // 3
    return 0;
}

STL 函数对象类模板:

  • std::lessstd::greater:这些模板用于比较两个值的大小。std::less返回true如果第一个参数小于第二个参数,而std::greater则返回true如果第一个参数大于第二个参数。
int a = 5, b = 10;
std::less<int> less_than;
std::greater<int> greater_than;
bool result1 = less_than(a, b); // result1 = true
bool result2 = greater_than(a, b); // result2 = false
  • std::plusstd::minus:这些模板用于执行加法和减法运算。
int a = 5, b = 10;
std::plus<int> add;
std::minus<int> subtract;
int result1 = add(a, b); // result1 = 15
int result2 = subtract(a, b); // result2 = -5
  • std::multipliesstd::divides:这些模板用于执行乘法和除法运算。
int a = 5, b = 10;
std::multiplies<int> multiply;
std::divides<int> divide;
int result1 = multiply(a, b); // result1 = 50
int result2 = divide(a, b); // result2 = 0

相关推荐

  1. 什么是CSTP测试认证,如何通过CSTP认证?

    2024-04-23 01:36:03       7 阅读
  2. media-ctl 生成拓扑和数据流图

    2024-04-23 01:36:03       40 阅读
  3. Golang time CST以及UTC介绍

    2024-04-23 01:36:03       8 阅读
  4. Hadoop 概述

    2024-04-23 01:36:03       30 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-04-23 01:36:03       19 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-23 01:36:03       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-23 01:36:03       20 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-23 01:36:03       20 阅读

热门阅读

  1. Linux bridge forwarding table

    2024-04-23 01:36:03       12 阅读
  2. 2024-04-22(AJAX)

    2024-04-23 01:36:03       13 阅读
  3. Ubuntu22.04.4 - 安装后使用笔记目录-VMware

    2024-04-23 01:36:03       15 阅读
  4. 基于Python对豆瓣电影数据爬虫的设计与实现

    2024-04-23 01:36:03       13 阅读
  5. Es批量删除DeleteByQueryRequestBuilder

    2024-04-23 01:36:03       14 阅读
  6. Unity3D 分块编辑小AStar地图详解

    2024-04-23 01:36:03       11 阅读
  7. 卸载并升级pytorch安装torcheval

    2024-04-23 01:36:03       13 阅读
  8. CV 面试指南—深度学习知识点总结(1)

    2024-04-23 01:36:03       15 阅读
  9. 前端CSS基础2(CSS基本选择器和复合选择器)

    2024-04-23 01:36:03       10 阅读
  10. 面试题

    面试题

    2024-04-23 01:36:03      16 阅读