4

I am trying to find an object in a vector of objects whos value of a member variable is true. Could it be done without defining a lamba function or function object, by just specifying the member variable itself:

class A
{
public:

   explicit A(bool v, int v2, float v3) : value(v), value2(v2), value3(v3)
   {}
   ...
   bool value;
   int value2;
   float value2;
   ...
}

int main()
{
    std::vector<A> v;
    v.push_back(A(false, 1, 1.0));
    v.push_back(A(true, 2, 2.0));
    v.push_back(A(false, 3, 3.0));

    auto iter = std::find_if(v.begin(), v.end(), &A::value);
}

Compiling as is above does not work as it assumes a A* and not A.

Not that its a problem to use lambdas, just curious.

thorsan
  • 1,034
  • 8
  • 19
  • What happened when you tried? – juanchopanza Jun 08 '16 at 08:59
  • @juanchopanza Didnt compile, requires A* as input is you use &A::value, and not A which is passed byt find_if – thorsan Jun 08 '16 at 09:01
  • 1
    Define an equality comparison operator for the class, that compares an instance of the class and a boolean value, and simply use [`std::find`](http://en.cppreference.com/w/cpp/algorithm/find)? You can't really get around the need to write some code to compare values. – Some programmer dude Jun 08 '16 at 09:05
  • @JoachimPileborg, The actual object is more complex so using the == operator would not work. This should be made more clear in the question. – thorsan Jun 08 '16 at 09:31

3 Answers3

8

You may use std::mem_fn

auto iter = std::find_if(v.begin(), v.end(), std::mem_fn(&A::value));

Demo

Note that range library should allow directly:

auto iter = range::find_if(v, &A::value);
Jarod42
  • 203,559
  • 14
  • 181
  • 302
3

If you cannot use C++11 lambdas, you can do that with std::bind:

auto iter = std::find_if(v.begin(), v.end(), std::bind(&A::value, std::placeholders::_1));
Maxim Egorushkin
  • 131,725
  • 17
  • 180
  • 271
0

A solution could be the following

  1. (Optional) Don't mark your constructor A(bool) as explicit to allow implicit conversion from bool to A (live demo on coliru)
  2. Overload operator==() so that it only uses value to establish equality.

You can also supply an operator==(bool v) { return value == v;} (see this demo)

Of course I would advise you not to use that solution as it is quite dirty. Just supply a predicate using std::find_if to do the job. Note that the said predicate must have an operator() so of course you cannot supply a value such as a bool as the predicate to std::find_if

Rerito
  • 5,886
  • 21
  • 47
  • My actual constructor is more complex, but otherwise a good approach – thorsan Jun 08 '16 at 09:28
  • @thorsan then just make an overloaded equality operator taking a bool argument as I suggested later on my answer. Though I find Jarod and Maxim answers much better – Rerito Jun 08 '16 at 09:30