我无法弄清楚为什么他们在C ++ STL中分离了算法,迭代器和容器。如果在任何地方大量使用模板,那么我们可以使用模板参数将所有内容放在一个地方。
我得到的一些文字解释了迭代器可以帮助算法与容器数据交互,但是如果容器暴露了一些机制来访问它拥有的数据呢?
答案 0 :(得分:24)
使用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个容器适配器,并且有近80个算法单独<algorithm>
(甚至不计算<numeric>
中的那些),这样您只有16 + 80
代替16 * 80
,代码减少了13倍! (当然,并非每个算法都适用于每个容器,但重点应该是明确的。)
迭代器可以分为5类(输入,输出,转发,双向和随机访问),一些算法将根据迭代器功能委托给专用版本。这将在一定程度上减少代码减少,但通过为手头的迭代器选择最适合的算法,可以大大提高效率。
请注意,STL在分离中并不完全一致:std::list
具有自己的sort
成员函数,该函数使用特定于实现的详细信息对自身进行排序,std::string
具有大量的成员函数算法,其中大多数可以作为非成员函数实现。