Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ lambda syntax

Tags:

c++

lambda

I have a function that searches a vector of iterators and returns the iterator if its names matches a string passed as an argument.

koalaGraph::PVertex lookUpByName(std::string Name, std::vector<koalaGraph::PVertex>& Vertices) {

    for (size_t i = 0; i < Vertices.size(); i++) {

        if(Vertices[i]->info.name == Name) 
            return Vertices[i];
    }
}

My question is how can I implement this as a lambda, to use it in connection with std::find_if?

I'm trying this:

std::vector<koalaGraph::PVertex> V;
std::string Name;
std::find_if(V.begin(), V.end(), [&Name]() {return Name == V->info.name;})

But it says that V

an enclosing-function local variable cannot be referenced in a lambda body unless it is in the capture list.

like image 214
black sheep Avatar asked Mar 19 '19 14:03

black sheep


3 Answers

find_if is going to pass the elements of the vector into your lambda. That means you need

std::find_if(V.begin(), V.end(), [&Name](auto const& V) {return Name == V->info.name;})

so that the V in the lambda body is the element of the vector, not the vector itself.


Ideally you'd give it a different name than V so you keep the vector and local variables separate like

std::find_if(V.begin(), V.end(), [&Name](auto const& element) {return Name == elememt->info.name;})

So now it is clear you are working on a element of the vector, instead of the vector itself.

like image 80
NathanOliver Avatar answered Sep 16 '22 15:09

NathanOliver


First, V->info.name is ill formed, inside or outside of the lambda.

The function object sent to the algoritm std::find_if must be a unary function. It must take the current element to check as a parameter.

auto found = std::find_if(
    V.begin(), V.end(), 
    [&Name](koalaGraph::PVertex const& item_to_check) {
        return Name == item_to_check->info.name;
    }
);

The type of found is an iterator to the element that has been found. If none is found, then it returns V.end()

If you use C++14 or better, you can even use generic lambdas:

auto found = std::find_if(
    V.begin(), V.end(), 
    [&Name](auto const& item_to_check) {
        return Name == item_to_check->info.name;
    }
);
like image 20
Guillaume Racicot Avatar answered Sep 18 '22 15:09

Guillaume Racicot


std::find_if's predicate will receive a reference to each element of the range in turn. You need:

std::find_if(
    V.begin(), V.end(),
    [&Name](koalaGraph::PVertex const &v) { return Name == v->info.name; }
);
like image 30
Quentin Avatar answered Sep 19 '22 15:09

Quentin