为什么std :: algorithms也不能直接在容器上工作?

为什么std :: algorithms也不能直接在容器上工作?

问题描述:

可能重复:
采用STL算法,而不是整个容器.begin(),end()为arg?

我一直在研究一些算法,我想知道为什么其中一些算法也没有采用容器的变体.

I have been looking at some algorithms and I am wondering why some of them don't also have a variation that takes in a container.

例如, find 可以接收一个容器和值,并且该算法可以通过调用 begin end 来在内部对该容器进行迭代容器.与 unique_copy 相同,在这里传递一个容器对我来说似乎更有用,并且该算法使用 push_back 而不是需要迭代器,在该迭代器中我将被迫将数组调整为最大大小元素计数. for_each 是另一个这样的示例.

For example, find can take in a container and value and the algorithm can internally iterator over the container by calling begin and end of the container. Same with unique_copy where it seems more useful to me to pass a container and the algorithm use push_back instead of requiring an iterator where I would be forced to resize the array to the maximum element count. for_each is another such example.

我确定有很多我不知道的理由吗?

I am sure there are good reasons I don't know about?

我看到的主要原因有两个:

There are two main reasons I can see:

  1. 为容器添加重载将使功能数量增加一倍以上:对于仅采用一个范围的每种算法,重载将增加一倍.但是,对于诸如 std :: copy()之类的东西,您有两个范围,它们中的每一个都希望独立地指定为范围(适当的抽象不是容器,顺便说一句,而是护林员)或一对迭代器,使其已经有4个重载.
  2. 一旦范围进入图片,还不清楚要返回什么.您的示例使用 std :: find(),当它以迭代器作为参数时,该函数显然会返回一个迭代器.当给定一个范围时,实际上返回另一个范围可能更为合理.更糟糕的是,除非您最初只有一个通过范围(例如,从流中读取内容),否则甚至可以选择两个不同的范围,即开始找到对象和找到对象结束.另一个维度可能是选择获取选定范围的副本,而不是由迭代器定界的范围.
  1. Adding overloads for containers would more than double the number of functions: For each algorithm taking just one range, the overloads would double. However, for something like std::copy() you have two ranges, each one of them independently wants to be specified either as range (the proper abstraction isn't containers, BTW, but rather rangers) or a pair of iterators, making it already 4 overloads.
  2. Once ranges enter the picture, it isn't entirely clear what needs to be returned. Your example uses std::find() which clearly returns an iterator when it gets iterators as arguments. When given a range, it may actually be much more reasonable to return another range. To make matters worse, unless you have a single pass range initially (e.g., something reading from a stream) there is even a choice of two different ranges, i.e., begin to found object, and found object to end. Another dimension could be a choice of getting a copy of the chosen range rather than a range delimited by iterators.

最初提出STL时,首先将其视为Crazy Talk!试图说服人们打开另一个主要的蠕虫罐来正确处理范围,可能很容易使整个想法丧生.紧接着的后续问题变成:为什么这没有改变?...而且这个问题也有两个答案:

When STL was proposed initially, it was considered Crazy Talk in the first place! Trying to convince people to open another major can of worms to deal with ranges properly could have easily killed off the entire idea. The immediate follow-up question then becomes: Why wasn't this changed? ... and there are two answers to this question as well:

  1. 我没有提议更改界面,尽管在我向图书馆工作组介绍该草案时认为该草案版本是合理的.但是,我提出的建议并没有引起很大的热情.另外,当时我还不知道如何以可接受的努力实际实现我设想的接口(我知道如何使用C ++ 2011功能).我已经开始写对STL新接口的描述,但是即使这样,还不完整,我最近还没有花时间来解决这个问题.
  2. 尽管我认为算法是正确的方法,但许多人还是故意不使用它们.我发现人们已经取代了算法的使用,因为据称编写一个执行操作的循环比调用算法可读性更高".不幸的是,在某些情况下,甚至确实如此,因为所涉及的功能对象简直是丑陋的.鉴于似乎很少有人使用这些算法,因此似乎没有动力去改变它们.
  1. I haven't proposed a changed interface although a draft version was considered to be reasonable when I presented it to the Library Working Group. The proposal I outlined wasn't met with great enthusiasm, however. Also, at the time I had no idea how to actually implement the interface I envisioned with acceptable effort (with C++ 2011 features I know how to do it). I have started to write a description of a new interface of STL but even this is incomplete and I haven't managed to take time to work on this recently.
  2. Although the algorithms are, in my opinion, the correct way to go, many people deliberately don't use them. I found cases where people have replaced uses of the algorithms because it is allegedly "more readable" to write a loop doing an operation than calling an algorithm. Unfortunately, this is, indeed, even true in some cases because the involved function objects are just hideous. Given that few people seem to use the algorithms there seems little incentive to change them.