C ++ lambda捕获此对比通过引用捕获

时间:2015-11-06 20:55:46

标签: c++ c++11 lambda std-function

如果我需要生成一个调用成员函数的lambda,我应该通过引用捕获还是捕获'this'?我的理解是'&'仅捕获使用的变量,但“this”捕获所有成员变量。最好使用'&'?

Context

4 个答案:

答案 0 :(得分:12)

对于您提供的具体示例,按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/

答案 1 :(得分:5)

Here很好地解释了&this以及其他人在捕获列表中使用时的含义。

在您的情况下,假设您所要做的就是调用当前正在执行的方法的this实际引用的实例的成员函数,将this放入您的捕获列表应该足够了。

答案 2 :(得分:2)

这不是一个明显的例子,它比另一个要好。相反,两者(至少可能)完成的事情略有不同。例如,考虑这样的代码:

#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仅捕获{em> 可通过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独有的。捕获任何指针将使您可以访问其指向的任何内容。

答案 3 :(得分:1)

捕获this并通过引用捕获是两个正交的概念。您可以使用one,both或none。通过引用捕获this没有意义,但您可以通过引用捕获其他变量,同时按值捕获this