Reputation: 91
I have this little for-loop here (variables and types renamed):
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"? I can't use Boost in that context, nor C++20 ranges or range-v3.
Thank you in advance.
Upvotes: 1
Views: 884
Reputation: 117298
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(); });
Upvotes: 1
Reputation: 473352
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::sort
's predicate compares pairs of values, not pairs of iterators. std::copy_if
copies values based on a predicate which is provided a value. And so forth. Even the range-based for
loop itself doesn't expose the iterators.
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).
}
}
Upvotes: 1