Std :: map find_if confusion state

I would like to use std :: find_if to search for the first element on my map that has a specific value in a specific element of its value structure. Although I'm a little confused. I think I need to use bind1st or bind2nd, but I'm not sure what the correct path is.

Here is some pseudo code:

struct ValueType { int x, int y, int z }; std::map<int, ValueType> myMap; ... {populate map} std::map<int, ValueType>::iterator pos = std::find_if(myMap.begin(), myMap.end(), <?>); 

So, let's say that I wanted to find the first element of the map, where the .x member of ValueType was equal to a specific integer value (which every call can change).

What would be the best way to write an object of a function or function to achieve this? I understand that there must be a unary predicate that makes me think that I will need bind1st or bind2nd to provide an integer value that I check, but I'm not sure how to do this. It has been too long since I looked at it !. > & L;

+8
c ++ stl
source share
7 answers

Elements on the map are not sorted by value, they are sorted according to the key. Thus, the phrase "first element" makes little sense.

To find some element (not the first) that has x equal to some value, you can write a functor as follows:

 struct check_x { check_x( int x ) : x_(x) {} bool operator()( const std::pair<int, ValueType>& v ) const { return v.second.x == x_; } private: int x_; }; 

Then use it as follows:

 // find any element where x equal to 10 std::find_if( myMap.begin(), myMap.end(), check_x(10) ); 
+15
source share

You can use lambda function

 int val = ...; auto it = std::find_if(myMap.begin(), myMap.end(), [val](const std::pair<int, ValueType> & t) -> bool { return t.second.x == val; } ); 

But since the answer of Cyril V. Lyadvinsky suggests that the "first" element may not be what you expect.

+11
source share
 struct Pred { Pred(int x) : x_(x) { } bool operator()(const std::pair<int, ValueType>& p) { return (x_ == p.second.x); } private: int x_; }; ... = std::find_if(myMap.begin(), myMap.end(), Pred(NUMBER)); 
+3
source share

If you want to search also in values, is it better to use Boost Bimap , so as not to be slow?

+1
source share

This has nothing to do with std::bind1st or std::bind2nd . First of all, you should keep in mind that map elements are key-value pairs, in your case std::pair<int,ValueType> . Then you just need a predicate that compares the x element of the second member of the yuch pair with a specific value:

 struct XEquals : std::unary_function<std::pair<int,ValueType>,bool> { XEquals(int _x) : x(_x) {} bool operator()(const std::pair<int,ValueType> &v) const { return p.second.x == x; } int x; }; 
+1
source share

using Boost.Bind and Boost.Lambda :

 ... #include <boost/bind.hpp> #include <boost/lambda/lambda.hpp> ... typedef std::map<int, ValueType> MapType; ... MapType::iterator pos = std::find_if(myMap.begin(), myMap.end(), boost::bind(&ValueType::y, boost::bind(&MapType::iterator::value_type::second, _1)) == magic_number); 
+1
source share

Based on all the answers above, I cheat with decltype with C ++ 11 semantics.

 auto beg_ = myMap.begin(); auto end_ = myMap.end(); auto it = find_if(beg_, end_, [&some_val](decltype(*beg_) & vt) { return vt.second == some_val;}); if (end_ != it) { auto key_found = (*it).first; } else { // throw error not found. } 
+1
source share

All Articles