How can I get std :: find_if and std :: map to work together with some boost library?

This question is inspired by another topic that poses this question:

Find the first value that exceeds the value specified by the user from the map container

which can be solved in several ways. A typical C ++ 03 solution defines a special function (or functor) and passes it to std::find_if as the third argument.

In C ++ 11, you can avoid defining a highlighted function (or functor) and use lambda instead as:

 auto it = std:: find_if(m.begin(), mp.end(), [n](const std::pair<std::string, int> & x) -> bool { return x.second > n; } ); 

which is the accepted answer .

I'm still looking for a short and cool solution. If it was a vector, then I just learned the cool solution that Boost.Phoenix uses, and the solution becomes very concise ( ideone demo )

 std::vector<int> v = ...; auto it = std::find_if(v.begin(), v.end(), arg1 > 4); 

Here arg1 is a functor object defined in the namespace boost::phoenix::arg_names , and the expression arg1>4 is evaluated by another functor, which is then passed to std::find_if .

Quick test: ( ideone ),

 std::cout<< (arg1 > 9)(v) << std::endl; //prints 0 if as v > 9 is false, else 1 //or store the functor first and then use it const auto & f = arg1 > 9; std::cout<< f(v) << std::endl; //prints 0 if as v > 9 is false, else 1 

My question is that I want to solve the problem with the card in a similar way. Is there such a solution? Sort of:

 auto it = std::find_if(m.begin(),mp.end(), (???).second > n); //m is std::map 

Or,

 auto it = std::find_if(m.begin(),mp.end(), at<1>(arg1) > n); //m is std::map 

For this to work, the expression at<1>(arg1) > 2 must be evaluated by a functor that takes const std::pair & as an argument. My gut feelings tell me boost has this solution. :-)

+6
source share
1 answer

Indeed, Boost.Fusion and Boost.Phoenix have exactly what you want to embed.

If one of them contains the necessary header for adapt std::pair<> as a Fusion matching sequence, then you can use the lazy version of boost::fusion::at_c<> Phoenix to access std::pair<>::first or std::pair<>::second (required #include <boost/phoenix/fusion.hpp> ).

 namespace phx = boost::phoenix; using phx::arg_names::arg1; auto it = std::find_if(m.begin(), m.end(), phx::at_c<1>(arg1) > n); 

EDIT: Full sample tested with VC ++ 2010 SP1 + Boost 1.47.0:

 #include <algorithm> #include <map> #include <string> #include <iostream> #include <boost/fusion/include/std_pair.hpp> #include <boost/phoenix/core.hpp> #include <boost/phoenix/operator.hpp> #include <boost/phoenix/fusion.hpp> int main() { namespace phx = boost::phoenix; using phx::arg_names::arg1; std::map<std::string, int> m; m["foo"] = 1; m["bar"] = 2; m["baz"] = 3; m["qux"] = 4; m["quux"] = 5; m["corge"] = 6; m["grault"] = 7; m["garply"] = 8; m["waldo"] = 9; m["fred"] = 10; m["plugh"] = 11; m["xyzzy"] = 12; m["thud"] = 13; int const n = 6; auto it = std::find_if(m.cbegin(), m.cend(), phx::at_c<1>(arg1) > n); if (it != m.cend()) std::cout << it->first << '\n'; // prints "fred" } 
+9
source

Source: https://habr.com/ru/post/896810/


All Articles