0

Here is a reproducible code

#include <iostream>
#include <vector>
#include <algorithm>

class X
{
public:
 int a; 
  X(int b)
  : a(b)
  {}
};

int main()
{
  // Build the vector 'v'
  std::vector<X> v;
  X x1(7);
  v.push_back(x1);
  X x2(11);
  v.push_back(x2);
  X x3(16);
  v.push_back(x3);
  X x4(20);
  v.push_back(x4);
  X x5(22);
  v.push_back(x5);
  X x6(31);
  v.push_back(x6);
  X x7(38);
  v.push_back(x7);

  // Search if there is an element of 'v' which attribute 'a' equals 18
  int y(18); 
  if (
    std::find(
        v.begin(),
        v.end(),
        [&](const X& o){return o.a == y;}
      ) == v.end()
    )
  {
    std::cout << "'y' is not present in 'v'\n";
  } else
  {
    std::cout << "'y' is present in 'v'\n";
  }

  return 0;
}

I try to compile with g++ -std=c++14 a.cpp -o a and get

 error: invalid operands to binary expression
      ('X' and 'const (lambda at a.cpp:38:5)')

I have tried a number of alternatives and read this and a number of SE posts including Error: variable “cannot be implicitly captured because no default capture mode has been specified” but I fail to see my mistake.

Community
  • 1
  • 1
Remi.b
  • 17,389
  • 28
  • 87
  • 168

2 Answers2

5

You're using std::find() with arguments that you should use with std::find_if().

If you use std::find() the third argumend should be a value of the container; a class X instance, in this case.

If you want that the third argument is an unary predicate (that receive a container value and return a bool), the right function is std::find_if().

Using a unary predicate as third argument for std::find(), the compiler try to equate a class X instance with the lambda function.

That is: the compiler try to compile

*(v.begin()) == [&](const X& o){return o.a == y;}

So the compiler error.

So try with

std::find_if(  // <-- std::find_if !
    v.begin(),
    v.end(),
    [&](const X& o){return o.a == y;}
  ) == v.end()
max66
  • 65,235
  • 10
  • 71
  • 111
1

If you want to stick with std::find, which, at third argument it expected the value to be compared, you need to provide an operator== to perform comparison.

You can try something like this:

(...)
bool operator==(const X& x, int b)
{
    return x.a == b;
}

and change std::find to:

std::find(
    v.begin(),
    v.end(),
    y
) == v.end()

but I prefer just changing std::find to std::find_if

Amadeus
  • 10,199
  • 3
  • 25
  • 31