Search code examples
c++c++11lambdaanonymous-functionstd-function

Saving an anonymous function (lambda) as function-typed variable


I'm using an anonymous function (also known as lambda) as condition-thing for find_if. Obviously I could make a special class for it, but C++11 says that I could use an anonymous function for that. However, for the sake of readability and understanding, I decided to save the anonymous function in a local variable typed as function.

Unfortunately, I get the error:

no match for call to '(std::function<bool(Point*, Point*)>) (Point*&)'
note: candidate is:
note: _Res std::function<_Res(_ArgTypes ...)>::operator()(_ArgTypes ...) const [with _Res = bool; _ArgTypes = {Point*, Point*}]
note:   candidate expects 2 arguments, 1 provided

What am i doing wrong? The so-called candidate is Greek to me. I tried to place the lambda directly in the find_if-invokement but that didn't work either.

#include <vector>
#include <function>
#include <algorithm>

using std::vector;
using std::function;
using std::find_if;

Point* Path::getPoint( int x, int y )
{
   function<bool( Point*, Point* )> howToFind = [&x, &y]( Point* a, Point* b ) -> bool
    {
        if( a->getX() == x )
        {
            return true;
        }
        else if( a->getX() < b->getX() )
        {
            return true;
        }
        else
        {
            return false;
        }
    };

    vector<Point*>::iterator foundYa = find_if( this->points.begin(), this->points.end(), howToFind );

    if( foundYa == points.end() )
    {
        return nullptr;
    }

    return *foundYa;
}


The corrected part of the code after cnicutar's helpful answer. I had to refactor my code at other places, but that's out of scope of this question:

function<bool( Point* )> howToFind = [&x, &y]( Point * a ) -> bool
{
    if( a == nullptr )
    {
        return false;
    }
    else
    {
        if( a->getX() == x && a->getY() == y )
        {
            return true;
        }
        else
        {
            return false;
        }
    }
}; 

Solution

  • According to cppreference the function must be a UnaryPredicate, i.e. it must take a single argument.

    template< class InputIt, class UnaryPredicate >    
    InputIt find_if( InputIt first, InputIt last,
                         UnaryPredicate q );