C++lambda通过引用捕获这个与捕获的比较
C++ lambda capture this vs capture by reference
如果我需要生成一个调用成员函数的lambda,我应该通过引用捕获还是捕获"this"?我的理解是仅捕获所使用的变量,但"this"捕获所有成员变量。所以最好使用"&"?
class MyClass {
public:
int mFunc() {
// accesses member variables
}
std::function<int()> get() {
//return [this] () { return this->mFunc(); };
// or
//return [&] () { return this->mFunc(); };
}
private:
// member variables
}
对于您提供的特定示例,this
捕获是您想要的。从概念上讲,通过引用捕获this
没有多大意义,因为您不能更改this
的值,所以只能将其用作访问类成员或获取类实例地址的指针。在lambda函数中,如果您访问隐式使用this
指针的东西(例如,您调用成员函数或访问成员变量而不显式使用this
),编译器会将其视为您无论如何都使用了this
。您也可以列出多个捕获,因此,如果您想同时捕获成员和局部变量,您可以独立选择是通过引用还是通过值来捕获它们。下面的文章应该让你对lambdas和捕获有一个很好的基础:
https://crascit.com/2015/03/01/lambdas-for-lunch/
此外,您的示例使用std::function
作为返回类型,lambda通过该返回类型传递回调用者。请注意,std::function
并不总是像你想象的那么便宜,所以如果你能够直接使用lambda,而不必将其封装在std::function
中,它可能会更高效。以下文章虽然与您最初的问题没有直接关系,但仍可能为您提供一些与lambdas和std::function
相关的有用材料(请参阅存储函数对象的另一种方法一节,但这篇文章通常可能会引起您的兴趣):
https://crascit.com/2015/06/03/on-leaving-scope-part-2/
这里很好地解释了&
、this
和其他在捕获列表中使用时的指示。
在您的情况下,假设您所要做的只是调用实例的成员函数,该成员函数实际上被当前执行的方法的this
引用,那么将this
放在捕获列表中就足够了。
捕获this
和通过引用捕获是两个正交的概念。您可以使用一个、两个或不使用。通过引用捕获this
是没有意义的,但您可以通过引用捕获其他变量,同时通过值捕获this
。
这不是一个明确的情况,on比另一个好。相反,两者(至少潜在地)完成的事情略有不同。例如,考虑这样的代码:
#include <iostream>
class foo {
int bar = 0;
public:
void baz() {
int bar = 1;
auto thing1 = [&] { bar = 2; };
auto thing2 = [this] { this->bar = 3; };
std::cout << "Before thing1: local bar: " << bar << ", this->bar: " << this->bar << "n";
thing1();
std::cout << "After thing1: local bar: " << bar << ", this->bar: " << this->bar << "n";
thing2();
std::cout << "After thing2: local bar: " << bar << ", this->bar: " << this->bar << "n";
}
};
int main() {
foo f;
f.baz();
}
如您所见,捕获this
仅捕获可通过this
引用的变量。在这种情况下,我们有一个局部变量来遮挡实例变量(是的,这通常是个坏主意,但在这种情况中,我们使用它来显示每个变量的部分功能)。正如我们在运行程序时所看到的,捕获this
与通过引用的隐式捕获()会得到不同的结果
Before thing1: local bar: 1, this->bar: 0
After thing1: local bar: 2, this->bar: 0
After thing2: local bar: 2, this->bar: 3
至于捕获所有内容与只捕获您使用的内容的细节:两者都不会捕获任何您不使用的变量。但是,由于this
是一个指针,捕获这个变量可以访问它指向的所有内容。不过,这并不是this
独有的。捕获任何指针都可以访问它指向的任何内容。
- 智能指针作为无序映射键,并通过引用进行比较
- 将指针与引用进行比较
- 使用模板专用化来比较指针引用
- 类型ID指针和引用比较差异?
- 通过查看程序集来比较按值传递与按引用传递性能
- std::具有自定义比较函数结果的排序函数错误:必须调用对非静态成员函数的引用
- 比较地图对象及其引用C++
- 将 Java 的按值传递与C++的按值传递或引用进行比较
- 使用比较函数对引用类型失败
- 正确编写引用的比较运算符
- 在C++中,如何让(嵌套)比较函子引用封闭类的数据
- 比较未引用的映射迭代器(std::pairs):C2678
- 如何比较两个 std::istream 引用
- C++ std::sort 引用另一个列表的自定义比较函数
- 正在比较JNI对象引用
- C++ 无法将取消引用的字符指针与字符进行比较
- C++lambda通过引用捕获这个与捕获的比较
- 比较身份引用的标准方法
- 更好的std::在指针集合上查找,并将取消引用的值与常量引用值进行比较
- 比较引用字符串和字符串