6

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

我一直在研究一些算法,我想知道为什么其中一些算法没有包含容器的变体。

例如,可以接收容器和值,并且算法可以通过调用容器的和来在容器find内部迭代。与传递容器和算法使用对我来说更有用的地方相同,而不是需要一个迭代器,在那里我将被迫将数组的大小调整为最大元素数。是另一个这样的例子。beginendunique_copypush_backfor_each

我确定有我不知道的充分理由吗?

4

3 回答 3

13

我可以看到有两个主要原因:

  1. 为容器添加重载将使函数数量增加一倍以上:对于每个算法只采用一个范围,重载将加倍。但是,对于像std::copy()你有两个范围的东西,它们中的每一个都独立地希望被指定为范围(正确的抽象不是容器,顺便说一句,而是游侠)或一对迭代器,使其已经有 4 个重载。
  2. 一旦范围进入图片,需要返回什么并不完全清楚。您的示例使用std::find()which 在将迭代器作为参数时清楚地返回一个迭代器。当给定一个范围时,返回另一个范围实际上可能更合理。更糟糕的是,除非您最初只有一个通过范围(例如,从流中读取的内容),否则甚至可以选择两个不同的范围,即开始找到对象和找到对象到结束。另一个维度可能是选择获取所选范围的副本,而不是由迭代器分隔的范围。

最初提出 STL 时,一开始就被认为是 Crazy Talk!试图说服人们打开另一个主要的蠕虫罐以正确处理范围可能很容易扼杀整个想法。紧接着的问题就变成了:为什么没有改变?...这个问题也有两个答案:

  1. 尽管当我将草稿版本提交给图书馆工作组时认为它是合理的,但我没有提议更改界面。然而,我概述的提议并没有得到极大的热情。此外,当时我不知道如何以可接受的努力实际实现我设想的接口(我知道如何使用 C++ 2011 特性)。我已经开始写一个关于 STL 新接口的描述,但即使这还不完整,我最近也没有花时间来处理这个问题。
  2. 尽管在我看来这些算法是正确的方法,但很多人故意不使用它们。我发现人们已经替换了算法的使用,因为据称编写循环执行操作比调用算法“更具可读性”。不幸的是,这在某些情况下甚至是真的,因为所涉及的函数对象是可怕的。鉴于似乎很少有人使用这些算法,似乎没有动力去改变它们。
于 2012-09-16T01:14:58.883 回答
2

如果要将结果放入容器而不预先分配元素,请使用插入迭代器。例如:

std::vector<int> elements;
// ...
std::vector<int> uniqueElements;
std::unique_copy(elements.begin(), elements.end(),
    std::back_inserter(uniqueElements));
于 2012-09-16T01:57:24.480 回答
2

采用迭代器的算法是最通用的。没有什么可以阻止您创建自己的便利函数,这些函数使用适当的参数调用标准算法。

于 2012-09-16T02:28:39.560 回答