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

Why don't std::algorithms work directly on containers as well?

本文关键字:工作 算法 std 为什么      更新时间:2023-10-16

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

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

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

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

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

当STL最初被提出时,它首先被认为是疯狂的谈话!试图说服人们打开另一个主要的蠕虫罐来正确处理范围很容易扼杀整个想法。接下来的直接问题就变成了:为什么没有改变?...这个问题也有两个答案:

  1. 我没有提出更改界面的建议,尽管当我向图书馆工作组提交草稿版本时,它被认为是合理的。然而,我概述的提议并没有引起极大的热情。此外,当时我不知道如何以可接受的努力实际实现我设想的界面(使用 2011 C++功能,我知道该怎么做(。我已经开始写一个关于STL新接口的描述,但即使这样也是不完整的,我最近还没有花时间来处理这个问题。
  2. 虽然在我看来,算法是正确的方法,但许多人故意不使用它们。我发现人们已经取代了算法的使用,因为据称编写一个执行操作的循环比调用算法"更具可读性"。不幸的是,在某些情况下,这确实是正确的,因为所涉及的函数对象非常可怕。鉴于似乎很少有人使用这些算法,因此似乎没有什么动力去改变它们。
如果要

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

std::vector<int> elements;
// ...
std::vector<int> uniqueElements;
std::unique_copy(elements.begin(), elements.end(),
    std::back_inserter(uniqueElements));

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