I'm attempting to capture the this
pointer within a lambda function that serves as the default parameter for a method.
My goal is to invoke a method of this class from within the lambda, which necessitates capturing the this
pointer.
However, the following code results in an error:
error C3639: a lambda that is part of a default argument can only have an init-capture
What is a common solution to overcome this limitation?
#include <functional>
class A{
public:
void B(std::function<void()> a = [this](){}); //error C3639: a lambda that is part of a default argument can only have an init-capture.
};
The problem with the line ...
void B(std::function<void()> a = [this](){});
... is that the lambda expression is default argument to a function parameter.
Function arguments are created at the call site, and there is no this
that could be captured at that point.
The C++ standard prohibits this
in default arguments:
[ Note: The keyword
this
may not appear in a default argument of a member function; see [expr.prim.this]. [ Example:class A { void f(A* p = this) { } // error };
— end example ] — end note ]
This is just a note, but it is true for lambdas as well because:
A lambda-expression appearing in a default argument shall not implicitly or explicitly capture any entity.
- [expr.prim.lambda.capture] p9
this
cannot be used in default argumentsA function call is processed as follows:
this
is now available)this
is no longer available)Note: the order of steps 4. and 5. is implementation-defined
You're trying to access this
in step 1, which is too early, not to mention that lambdas in default arguments can't have captures in general.
Adding a second overload such as
void B() { B( [this] {} ); }
would fix the problem, but you would end up with two functions instead of one.