【问题标题】:How can I replace this for loop with an STL implementation?如何用 STL 实现替换这个 for 循环?
【发布时间】:2020-03-21 05:12:21
【问题描述】:

我在这里有这个小 for 循环(变量和类型重命名):

vector<Iterator> validIterators;

for (auto itr = someStartIterator; itr != someVector.end(); itr++)
{
  if (itr->foo() && itr->bar())
    validIterators.push_back(itr); // Notice that I'm not deferencing the iterator when adding it to the vector
}

...

for (const auto& itr : validIterators)
{
  // Do stuff with the iterator explicitly (e.g. std::distance),
  // and not the object that it points (at least not at first).
}

有什么方法可以使用 STL &lt;algorithm&gt; 函数来使某些东西“更干净”吗?我不能在那种情况下使用 Boost,也不能使用 C++20 范围或 range-v3。

提前谢谢你。

【问题讨论】:

  • 如果我理解正确你可以使用标准算法 std::copy_if
  • ...变成back_inserter
  • @VladfromMoscow 最初是我的直觉,但我确实需要实际的迭代器,而不是它指向的对象的副本。
  • @FireYoshi -- ??当您使用copy_if 时,您正在获取迭代器。
  • @PaulMcKenzie copy_if 提供的唯一迭代器是“目标范围内元素的迭代器,在复制的最后一个元素之后”作为其返回值。否则元素将按值复制:en.cppreference.com/w/cpp/algorithm/copy

标签: c++ functional-programming stl iterator c++17


【解决方案1】:

就其本质而言,算法对值序列进行操作。它们通过称为“迭代器”的中间对象与这些值序列交互。但从实现的角度来看,这是一个实现细节。可以肯定的是,它是必要的,但它仍然不是算法的一部分。

因此,算法通常不会将迭代器暴露给用户提供的函子。 std::for_each 传递函子一个从迭代器中提取的值,而不是迭代器本身。 std::sort 的谓词比较成对的值,而不是成对的迭代器。 std::copy_if 根据提供值的谓词复制值。等等。即使是基于范围的 for 循环本身也不会暴露迭代器。

算法通过它们的迭代器而不是迭代器本身来操作值。

最好的办法是手动执行循环并将“作用于迭代器”部分折叠到条件测试部分中。

for (auto itr = someStartIterator; itr != someVector.end(); itr++)
{
  if (itr->foo() && itr->bar())
  {
    // Do stuff with the `itr` explicitly (e.g. std::distance).
  }
}

【讨论】:

  • 谢谢,看了你的回答后,我意识到validIterators 没有任何用处;在条件中折叠它更有意义。
【解决方案2】:

标准库算法使用迭代器来处理一些底层数据,而迭代器本身不能通过标准库算法获得。您必须为此编写自己的算法。

例子:

template<class Iterator, class Func>
std::vector<Iterator> get_valid_iterators(Iterator Begin, Iterator End, Func f) {
    std::vector<Iterator> rv;

    for(; Begin != End; ++Begin)
        if(f(Begin)) rv.push_back(Begin); // f is functor that can validate the iterator

    return rv;
}

用法:

auto vi = get_valid_iterators(container.begin(), container.end(),
                              [](auto& it) { return it->foo() && it->bar(); });

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-24
    • 1970-01-01
    • 2022-01-23
    • 1970-01-01
    • 2019-04-04
    • 2018-08-20
    相关资源
    最近更新 更多