为什么C++ STL 中算法、迭代器和容器是分开的

Why is there a separation of algorithms, iterators and containers in C++ STL

本文关键字:迭代器 STL C++ 算法 为什么      更新时间:2023-10-16

我不知道为什么他们在STL中分离C++算法,迭代器和容器。如果到处都大量使用模板,那么我们可以让类将所有内容放在一个带有模板参数的地方。

我得到的一些文字解释说,迭代器有助于算法与容器数据进行交互,但如果容器公开一些机制来访问它拥有的数据怎么办?

使用M容器 + N 算法,通常需要M * N段代码,但使用迭代器充当"胶水",这可以减少到M + N段代码。

示例:在 3 个容器上运行 2 个算法

std::list<int> l = { 0, 2, 5, 6, 3, 1 }; // C++11 initializer lists
std::vector<int> v = { 0, 2, 5, 6, 3, 1 };  // C++11 initializer lists
std::array<int, 5> a = { 0, 2, 5, 6, 3, 1 };
auto l_contains1 = std::find(l.begin(), l.end(), 1) != l.end();
auto v_contains5 = std::find(v.begin(), v.end(), 5) != v.end();
auto a_contains3 = std::find(a.begin(), a.end(), 3) != a.end();
auto l_count1 = std::count(l.begin(), l.end(), 1);
auto v_count5 = std::count(v.begin(), v.end(), 5);
auto a_count3 = std::count(a.begin(), a.end(), 3);

您只调用 2 种不同的算法,并且只有 3 个容器的代码。每个容器将begin()传递,并将迭代器end()传递给容器。即使您有3 * 2行代码来生成答案,也只需要编写3 + 2功能片段。

对于更多的容器和算法,这种分离大大减少了代码的组合爆炸,否则会随之而来:STL 中有 5 个序列容器、8 个关联容器和 3 个容器适配器,仅<algorithm>就有近 80 种算法(甚至不包括 <numeric> 中的算法),因此您只有 16 + 80 而不是 16 * 80 , 代码减少 13 倍!(当然,并非每个算法在每个容器上都有意义,但重点应该很清楚)。

迭代器可以分为 5 类(输入、输出、前向、双向和随机访问),一些算法会根据迭代器的能力委托给专用版本。这将在一定程度上减少代码减少,但通过选择最适合手头迭代器的算法来大大提高效率。

请注意,STL 在分离中并不完全一致:std::list有自己的 sort 成员函数,该函数使用特定于实现的详细信息对自身进行排序,并且 std::string 具有大量成员函数算法,其中大多数可以作为非成员函数实现。