简体   繁体   中英

C++ Passing lambda as function parameter with argument list

At the moment I'm trying to build something like a Java-like forEach in a class where I pass a lambda and it gets called for every item. At the moment I've implemented it like this:

Foo.h

class Foo
{
public:
    Foo();
    void forEach(void(*lambda)(Bar*));
private:
    SpecialList mElements;
};

Foo.cpp

#include "Foo.h"

void Foo::forEach(void(*lambda)(Bar*))
{
    for (auto& v : mElements)
    {
        // Try/catch for stopping
        try {lambda(&v.second);}
        catch (int) {break;}
    }
}

main.cpp

int main() {
    Foo foo();
    foo.forEach([](Bar* bar) {
        std::cout << bar->something() << std::endl;
    });
    return 0;
}

It works just fine, but I want to be able to pass elements by reference into the lambda to be able to work with later like in this example:

main.cpp

int main() {
    Foo foo();
    foo.forEach([&var1](Bar* bar) {
        std::cout << var1 << bar->something() << std::endl;
    });
    return 0;
}

How could we achieve something like this? I've been trying but it gives the error no suitable conversion function from... to... and tried searching for previous questions and taking a look at how functions like std::for_each work but cannot make heads or toes of that. Thanks.

A lambda is not a function pointer. If it has no captured objects, it can be implicitly converted to one, otherwise it cannot.

A lambda has a anonymous type, so if you want to use the type directly, you need to use templates:

template<typename Callable>
void Foo::forEach(Callable lambda)
{
    for (auto& v : mElements)
    {
        // Try/catch for stopping
        try {lambda(&v.second);}
        catch (int) {break;}
    }
}

Otherwise, a lambda is always convertable to a std::function (even when you capture objects), so you could write like this:

void Foo::forEach(std::function<void(Bar*)> lambda)
{
    for (auto& v : mElements)
    {
        // Try/catch for stopping
        try {lambda(&v.second);}
        catch (int) {break;}
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM