Reputation: 379
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:
class Foo
{
public:
Foo();
void forEach(void(*lambda)(Bar*));
private:
SpecialList mElements;
};
#include "Foo.h"
void Foo::forEach(void(*lambda)(Bar*))
{
for (auto& v : mElements)
{
// Try/catch for stopping
try {lambda(&v.second);}
catch (int) {break;}
}
}
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:
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.
Upvotes: 1
Views: 268
Reputation: 1383
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;}
}
}
Upvotes: 4