Reputation: 503
Suppose I have STL container with std::pair. Is there any way to adapt pair's second for STL algorithm lambda using boost?
std::vector<std::pair<int, SomeStruct>> vec;
const auto Predicate = [](SomeStruct const& s) { ... };
auto it = std::find_if(vec.begin(), vec.end(), boost-magic(Predicate));
Upvotes: 1
Views: 313
Reputation: 1596
Using the headers boost/range/algorithm/find_if.hpp
and boost/range/adaptor/transformed.hpp
you could use:
auto it = boost::find_if(vec | boost::adaptors::transformed(
[](std::pair<int, SomeStruct>& p){ return p.second; }),Predicate);
I am not aware of something shorter than [](std::pair<int, MyClass>& p){ return p.second; }
. A raw std::get<1>
does not work in this context, since it is not a functor. But my c++14-compiler also accepted the expression [](auto& p){ return std::get<1>(p); }
or [](auto& p){ return p.second; }
Update: You can use boost::phoenix::at_c<0>(boost::phoenix::arg_names::arg1)
to obtain a function accessing the first
member of the pair and boost::lambda::bind(Predicate,boost::lambda::_1)
to make Predicate
work together with this function and boost::lambda's comma-operator overload to combine both:
auto it = boost::find_if(vec, (boost::lambda::bind(Predicate,boost::lambda::_1),boost::phoenix::at_c<0>(boost::phoenix::arg_names::arg1)));
But I wouldn't call this "boost-magic", it is more like making things unnecessary complex.
Upvotes: 2
Reputation: 238361
No need for boost. You can simply write a lambda, or a named function object:
const auto Predicate2 = [&Predicate](std::pair<int, SomeStruct> const& s) {
return Predicate(s.second);
};
auto it = std::find_if(vec.begin(), vec.end(), Predicate2);
Of course, if Predicate
is only ever used in this one case, then it would make more sense to write it to accept a pair directly.
Upvotes: 6