为什么C++ STL 中算法、迭代器和容器是分开的
Why is there a separation of algorithms, iterators and containers in C++ STL
我不知道为什么他们在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
具有大量成员函数算法,其中大多数可以作为非成员函数实现。
相关文章:
- 自定义 STL 兼容迭代器,用于迭代 2D 数组类的列
- "迭代器"和"const_iterator"不是 STL 容器的必需成员?
- 没有 STL 容器的迭代器
- 为什么某些 STL 容器(堆栈、队列、优先级队列)不支持迭代器?
- 迭代器 STL C++是模板、类还是接口?
- 为什么我们不在 STL 的迭代器中传递星号(*)
- 成员函数不能为集合迭代器和const_iterator的输入重载(但可以为其他 STL 迭代器重载)
- 如何在C++中重新实现包含指针的 STL 容器的类的迭代器
- C++如何获取传递给函数(STL 迭代器)的参数的名称
- 迭代器和 STL 容器的关系
- C++ 中 STL 中迭代器的大小(以字节为单位)是多少
- 如何将 stl 迭代器与特征一起使用?
- 用于 STL 迭代器、指针和 std::nullptr_t 的模板函数
- 在 stl 容器包装器中定义迭代器类型
- 在多个 STL 对对象上创建迭代器
- 如何为获取 stl 容器迭代器的函数提供函数签名?
- 在 stl 算法中移动迭代器
- lower_bound 在 C++ STL 中返回迭代器,即使元素不存在也是如此.如何避免这种情况?
- 并行STL插入迭代器,例如std :: back_insert_iterator
- STL 迭代器继承:"value_type"不命名类型