C++ 为什么不是';stl中每个集合类型的每个成员函数是否都有一个?

C++ 为什么不是';stl中每个集合类型的每个成员函数是否都有一个?,c++,stl,foreach,standards,C++,Stl,Foreach,Standards,例如: v.for_each([](int i) { printf("%d\n", i); }); 如果比常用的更优雅、可读性更强: std::for_each(v.begin(), v.end(), [](int i) { printf("%d\n", i); }); 标准中缺少此类成员函数是否有正当理由 这是整个库的标准设计原理:将容器与算法分开 如果您按照自己的方式来做,那么您必须为每个容器Y实现每个特性X,如果您有M个特性和N个容器,那么您将得到M*N实现 通过使用迭代器并使算法在

例如:

v.for_each([](int i) { printf("%d\n", i); }); 
如果比常用的更优雅、可读性更强:

std::for_each(v.begin(), v.end(), [](int i) { printf("%d\n", i); });

标准中缺少此类成员函数是否有正当理由

这是整个库的标准设计原理:将容器与算法分开

如果您按照自己的方式来做,那么您必须为每个容器Y实现每个特性X,如果您有M个特性和N个容器,那么您将得到M*N实现

通过使用迭代器并使算法在迭代器而不是容器上工作,您只需实现M个算法和N个迭代器接口


这种分离还意味着您有无限广阔的应用范围:算法不能只用于每个库容器,而是用于任何人决定编写并配备迭代器的任何容器,无论是现在还是将来。有限重用与无限重用是一个相当有力的论据!通过通用的、免费的接口调用算法不会增加任何成本。

简单的事实是,标准库设计是在语言没有提供很多功能的时候出现的,而现在许多常见的设计,例如基于CRTP的混音器,都不存在。这意味着现在显而易见的优秀设计在创建标准库时根本无法实现或设计

迭代器是一个很好的泛型实现,但它们的泛型接口很糟糕。我感到悲哀的是,他们没有解决库设计中的问题并对其进行彻底检修,而是为问题的一小部分引入了一个特例语言特性。

template
template <class InputIterator, class UnaryFunction>
UnaryFunction for_each(InputIterator first, InputIterator last, UnaryFunction f);
每个_的一元函数(先输入计算器,后输入计算器,一元函数f);

如您所见,对于_,每个都将输入迭代器作为in参数,因此任何可以提供输入迭代器兼容的stl容器(这意味着除了输入迭代器之外,它还可以是双向的、随机访问迭代器等)都将与std::for_兼容。通过这种方式设计,stl通用算法可以从数据类型(容器)中分离出来,而数据类型(容器)更优雅、更通用。

为什么需要它

成员函数只有在实现效率更高的情况下才起作用(set::find比set上的std::find()更有效)

PS哦,如果您想避免无处不在的
.begin()
,en
.end()
调用,请使用。甜合成糖

随机增压范围启发示例:

#include <boost/range/adaptors.hpp>
#include <boost/range/algorithm.hpp>
#include <boost/pending/integer_range.hpp>

using namespace boost::adaptors;

static int mod7(int v) 
    { return v % 7; }

int main() 
{
    std::vector<int> v;

    boost::copy(
            boost::make_integer_range(1,100) | transformed(mod7), 
            std::back_inserter(v));

    boost::sort(v);

    boost::copy(
            v | reversed | uniqued, 
            std::ostream_iterator<int>(std::cout, ", "));
}
#包括
#包括
#包括
使用名称空间boost::适配器;
静态int mod7(int v)
{返回v%7;}
int main()
{
std::向量v;
复制(
boost::使_整数_范围(1100)|变换(mod7),
标准:背部插入器(v);
boost::sort(v);
复制(
v |反向|唯一,
std::ostream_迭代器(std::cout,“,”);
}

mixin可以用来缓解这个问题-您可以编写一个通用的功能mixin,它可以在任何容器上运行。@DeadMG:您如何使用mixing来为每个容器(例如,正则表达式匹配的集合或目录遍历)执行一个for-each操作?容器从mixin继承,它在引擎盖下使用迭代器来提供功能。只要对象提供迭代器(与现在完全一样),那么mixin就可以使用OP中显示的接口将该支持转换为简单的成员函数。此外,它实际上更通用,因为如果需要,您可以自己重写容器类中的功能-例如。,
std::list
@DeadMG:我认为这是可能的,不过这也会增加算法和容器之间更紧密的耦合-每次编写新算法时,都必须重新定义所有容器类。。。我想有人可以提供混音器作为可选工具,但就总体设计理念而言,它们似乎没有当前解决方案那么优雅。@DeadMG:但是超级混音器如何知道所有算法,过去、现在和未来?它如何扩展并提供与迭代器和算法相同的无限扩展性?算法和容器都可以来自许多不同的、不相关的来源。为什么需要它?成员函数只有在实现效率更高的情况下才起作用(set::find比set上的std::find()更有效)。哦,如果您想避免无处不在的
.begin()
,en
.end()
调用,请使用。甜蜜句法sugar@sehe:或效率较低,如
std::list::sort()
:-)@Kerrek:
std::list::sort
是特殊的,
std::sort
需要
RandomAccessIterator
,所以它对列表不起作用。你能举一个小例子,说明mixin可以适应任何未来的容器和算法吗?@Kerrek:它不一定非得如此。我们可以使用现有的对未来算法的支持,未来的容器可以从中继承,我们可以为最常用的算法提供更好的支持。我明白了。好吧,能提供这个就好了。听起来这可以作为可选功能集添加。。。