I'm defining a class like this:
class foo {
public:
// I define const and non-const versions of the 'visit' function
// nb. the lambda is passed by reference
virtual void visitWith(std::function<void(foo&)>&);
virtual void visitWith(std::function<void(const foo&)>&) const;
};
foo can have children so the idea is to visit a foo and all it's children recursively.
When I try to use it, eg. like this:
foo f;
f.visitWith([&](const foo&) {
// Do something here
});
I get compiler errors. The compiler can't figure out what to do.
I can make it work it by adding a typecast like this:
foo f;
f.visitWith( (std::function<void(const foo&)>) [&](const foo&) {
// Do something here
});
But that's horrible.
How can I get it to work neatly?
Edit:
This may be a problem with Visual C++, it refuses to compile the code given here:
https://ideone.com/n9bySW
The VC++ output when I try to compile it is:
Edit2: Nope, Visual C++ is correct, the code is ambiguous. See my solution below...
A lambda is a compiler-generated type, it is not an instance of std::function
, but it is assignable to one.
Your visitWith()
method takes a std::function
by non-const reference, which means it requires a pre-existing std::function
object, eg:
std::function<void(const foo&)> func = [&](const foo&) {
// Do something here
};
foo f;
f.visitWith(func);
Passing a lambda directly to visitWith()
would require the compiler to create a temporary std::function
object, but a non-const reference cannot bind to a temporary object. That is why your original code fails to compile.
For what you are attempting, you will have to pass the std::function
either by value or by const-reference instead:
class foo {
public:
void visitWith(std::function<void(foo&)>);
void visitWith(std::function<void(const foo&)>) const;
};
Live Demo
class foo {
public:
void visitWith(const std::function<void(foo&)> &);
void visitWith(const std::function<void(const foo&)> &) const;
};
Live Demo
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With