If I capture the "this"-ptr in a lambda I can call member functions without problems. However, when I instead capture the pointer explicitely (without mentioning "this"), it stops working. Am I doing something wrong? According to my understanding, the pointers should be the very same, so this really surprised me. Is there some compiler magic going on to treat "this" in a special way?
#include <cstdio>
#include <string>
struct client
{
auto foo(std::string&& other)
{
printf("%s!\n", other.data());
}
void local()
{
std::string str = "Hello World this is a sentence to long for sso!";
auto lambda = [this, other = std::move(str)]() mutable {
foo(std::move(other));
}();
}
static auto external(void* ptr) {
std::string str = "Hello World this is a sentence to long for sso!";
client* conv_ptr = static_cast<client*>(ptr);
auto lambda = [conv_ptr, other = std::move(str)]() mutable {
foo(std::move(other));
}();
}
};
int main()
{
client c1;
c1.local();
client::external(static_cast<void*>(&c1));
}
Yields:
<source>:15:14: error: 'void lambda' has incomplete type
15 | auto lambda = [this, other = std::move(str)]() mutable {
| ^~~~~~
<source>: In lambda function:
<source>:25:16: error: cannot call member function 'auto client::foo(std::string&&)' without object
25 | foo(std::move(other));
| ~~~^~~~~~~~~~~~~~~~~~
The return type of
client::fooisvoid, and you're assigning the return values of it to the twolambdas. The variable namelambdais confusing, since the right hand side of the assignment is actually an immediately invoked lambda expression, not just a lambda.In the second lambda, since
thisis not captured, the compiler does not have a way to callfooanymore. Since the intention is to callfoovia the pointerconv_ptr, use it explicitly.To quote from Lambda expressions on cppreference:
Therefore, for class members that are accessible by
this->member_name, thethis->part can be omitted, as it can also be omitted in the context of the lambda-expression, which is within a member function of the class. However, this does not apply to theconv_ptrpointer, sinceconv_ptr->foo()does not mean the same thing asfoo()(which is equivalent tothis->foo()) in the context.To make the code compile, remove the invocations
()from both lambdas, and callfoousingconv_ptr->foo.Try it on godbolt