In boost::adaptors::filtered
the filter function is used likeso:
std::vector<int> input;
input += 1,2,3,4,5,6,7,8,9;
boost::copy(
input | filtered(is_even()),
std::ostream_iterator<int>(std::cout, ","));
What is the effect of the pipe operator in this case? It is not defined for std::vector
, is it an overload? If so, how does one effectively search for such operators in libraires like boost?
This is a Boost Range Adaptor. Some more documentation has been written in this online book "The Boost C++ Libraries".
There are many such ranges, which can be composed to write high-level functional effect. Examples are here:
filtered
adaptorinput | filtered(is_even())
creates a temporary instance of the adaptor type:
boost::range_detail::filtered_range<is_even, std::vector<int> >
That's a type that models the Range Concept and holds a reference to the source range (input
) as well as a copy of the filter predicate (is_even()
).
The Range Concept is then implemented such that iteration of the range yields a bidirectional range as if it had only the elements of the source range that satisfy the filter predicate. You could equally write:
is_even predicate;
for (auto const& i : input)
if (predicate(i))
std::cout << i << ",";
range | adaptor
is an expression template that generates a new adapted range.
|
?The real answer is "because that's how it's designed and documented". The more technical explanation is because filtered(is_even())
is of type boost::range_detail::filter_holder<is_even>
which has an overloaded operator |
:
template< class SinglePassRange, class Predicate >
inline filtered_range<Predicate, SinglePassRange>
operator|(SinglePassRange& r,
const filter_holder<Predicate>& f)
{
BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<SinglePassRange>));
return filtered_range<Predicate, SinglePassRange>( f.val, r );
}
Note: The assert only verifies the minimum required traversal category. As documented you'll get "The minimum of the range category of rng and Bidirectional Range", which is a Bidirectional Range in this case (because vector has random traversal).
I am already lost at input += 1,2,.... – user463035818 56 mins ago
That's Boost Assign, unrelated to the range adaptor, I'd venture that C++11 makes it largely obsolete, because you can easily say
std::vector<int> input { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
Or indeed
std::vector<int> input;
input.insert(input.end(), { 1, 2, 3, 4, 5, 6, 7, 8, 9 });
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With