提问人:glades 提问时间:12/19/2022 更新时间:12/19/2022 访问量:292
为什么 lambda 捕获中的“this”与指向同一对象的指针的处理方式不同?
Why is "this" in lambda capture treated differently than pointer to the same object?
问:
如果我在 lambda 中捕获“this”-ptr,我可以毫无问题地调用成员函数。但是,当我显式捕获指针时(不提及“this”),它停止工作。我做错了什么吗?根据我的理解,指针应该是一样的,所以这真的让我感到惊讶。是否有一些编译器魔术以特殊方式处理“这个”?
#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));
}
收益 率:
<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));
| ~~~^~~~~~~~~~~~~~~~~~
答:
5赞
kotatsuyaki
12/19/2022
#1
返回类型为 ,您将它的返回值分配给两个 s。变量名称令人困惑,因为赋值的右侧实际上是立即调用的 lambda 表达式,而不仅仅是 lambda。
client::foo
void
lambda
lambda
在第二个 lambda 中,由于未捕获,编译器无法再调用。由于目的是通过指针调用,因此显式使用它。
this
foo
foo
conv_ptr
要引用 cpppreference 上的 Lambda 表达式,请执行以下操作:
为了查找名称、确定指针的类型和值以及访问非静态类成员,在 lambda 表达式的上下文中考虑闭包类型的函数调用运算符或运算符模板的主体。
this
因此,对于可由 访问的类成员,可以省略该部分,因为在 lambda-expression 的上下文中也可以省略该部分,该函数位于类的成员函数中。但是,这不适用于指针,因为在上下文中与指针的含义不同(等效于 )。
this->member_name
this->
conv_ptr
conv_ptr->foo()
foo()
this->foo()
要使代码可编译,请从两个 lambda 中删除调用,然后使用 调用。()
foo
conv_ptr->foo
#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 {
conv_ptr->foo(std::move(other));
};
}
};
int main()
{
client c1;
c1.local();
client::external(static_cast<void*>(&c1));
}
评论
this
[this = conv_ptr, other = std::move(str)](){...}
void
void
void lambda;