Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using find_if on map to find by value

Tags:

c++

stl

I have a class which has a map. I need to find iterator in map by searching for a particualar value, instad of the key. Using a member function predicate IsValueFound, am trying this.

class A
{
public:
  void findVal();
private:
 int state;
 map<int, int> exmap;
 bool IsValueFound(pair<int key, int val> itr)
 {
   return state == itr.second;
 }
};

void A::findVal
{
  itr = find_if(exmap.begin, exmap.end, mem_fun1_ref(&A::IsValueFound));
}

Iam getting compilation errors. Iam not sure whats the syntax for these function adaptors. Please help.

EDIT: Sorry. Please neglect the compilation errors arising other than from finf_if stmt. I need to get find_if stmt corrected first. Also the code doesn't have boost :(

like image 790
excray Avatar asked Dec 21 '22 19:12

excray


2 Answers

Its slightly easier to convert the object A into a functor:
But there were other problems with your code (see below):

#include <map>
#include <memory>
#include <functional>
#include <algorithm>

using namespace std;

class A {
    public:
      void findVal();
    private:
      int state;
      map<int, int> exmap;

      // Changed the function IsValueFound() to operator()
      // This makes the whole object behave like a function.
      // Its a lot easier then getting member functions and binding
      // the this reference.
      bool operator()(map<int,int>::value_type const& itr) const
                    //         ^^^^^^^^^^^^^^^^^
                    //  std::pair<int,int> is not the type held in the map
                    //  so you are not going to bind against it using a pair.
      {
          return state == itr.second;
      }
};

void A::findVal()
{
    // You did not specify a type
    // for the iterator in your code.
    std::map<int,int>::iterator itr1 = find_if(exmap.begin(), exmap.end(), *this);
                                                   //   ^^^^^^       ^^^^^^
                                                   // begin() and end() are methods.

    // Just pass the `this` object as the the third parameter it will act as a function now.
}
like image 192
Martin York Avatar answered Dec 31 '22 02:12

Martin York


Edit: there's obviously an error in my answer, mem_fun1_ref(&A::IsValueFound) doesn't work as a predicate for std::find_if. I'm working on correcting that.

you forgot parenthesis with exmap.begin and exmap.end. I think if you had read the compilation error report, it would have told seomthing about it.

I would write that this way:

typedef map<int, int>::const_iterator MyIterator
void A::findVal()
{
    const MyIterator itrBegin = exmap.begin();
    const MyIterator itrEnd = exmap.end();
    MyIterator itrFound = find_if( itrBegin ,
                                   itrEnd ,
                                   mem_fun1_ref(&A::IsValueFound));    
}

but I havent't tried mem_fun1_ref(&A::IsValueFound) to compile. and I'm not used to using mem_fun1_ref, I always redefine my own functor with their operator().

like image 37
Stephane Rolland Avatar answered Dec 31 '22 02:12

Stephane Rolland