简体   繁体   English

如何用 STL 实现替换这个 for 循环?

[英]How can I replace this for loop with an STL implementation?

I have this little for-loop here (variables and types renamed):我在这里有这个小的 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).
}

Is there any way to use the STL <algorithm> functions to make something "cleaner"?有什么方法可以使用 STL <algorithm>函数来制作“更干净”的东西? I can't use Boost in that context, nor C++20 ranges or range-v3.我不能在那种情况下使用 Boost,也不能使用 C++20 范围或范围 v3。

Thank you in advance.先感谢您。

Algorithms, by their nature, operate on sequences of values.就其性质而言,算法对值序列进行操作。 They interface with these sequence of values through an intermediary object called an "iterator".它们通过称为“迭代器”的中间对象与这些值序列进行交互。 But this is, from the implementation's perspective, an implementation detail.但从实现的角度来看,这是一个实现细节。 A necessary one, to be sure, but it is still not really part of the algorithm.可以肯定的是,这是必要的,但它仍然不是算法的真正组成部分。

As such, algorithms do not typically expose the iterators to user-provided functors.因此,算法通常不会将迭代器暴露给用户提供的函子。 std::for_each passes the functor a value extracted from the iterator, not the iterator itself. std::for_each向函子传递一个从迭代器中提取的值,而不是迭代器本身。 std::sort 's predicate compares pairs of values, not pairs of iterators. std::sort的谓词比较值对,而不是迭代器对。 std::copy_if copies values based on a predicate which is provided a value. std::copy_if根据提供值的谓词复制值。 And so forth.等等。 Even the range-based for loop itself doesn't expose the iterators.即使是基于范围的for循环本身也不暴露迭代器。

Algorithms manipulate values through their iterators, not the iterators themselves.算法通过它们的迭代器来操作值,而不是迭代器本身。

Your best bet is to do the loop manually and fold the "act on the iterator" part into the conditional testing part.最好的办法是手动执行循环并将“对迭代器执行操作”部分折叠到条件测试部分中。

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

The standard library algorithms uses iterators to work on some underlying data and the iterators themselves are not available through the standard library algorithms.标准库算法使用迭代器来处理一些底层数据,而迭代器本身无法通过标准库算法获得。 You'll have to write your own algorithm for that.您必须为此编写自己的算法。

Example:例子:

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;
}

Usage:用法:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM