什么是在c ++ 11中按值捕获成员变量的好方法?

时间:2016-02-05 18:50:37

标签: c++ c++11 g++

struct myclass {
myclass(){}
myclass(int qx):z(qx){   }
std::function<void()> create() {
    auto px = [z](){
        std::cout << z << std::endl;
    };
    return px;
}
int z;
};

myclass my;
my.z = 2;
auto func = my.create();
func();
my.z = 3;
func();

这段代码将在4.6.3中编译,这将做正确的事情来制作成员变量z的副本,并且两个打印都将得到2.在4.8.2中,这不再编译..

error: ‘this’ was not captured for this lambda function

我想知道为什么删除此功能,因为它非常有用。

2 个答案:

答案 0 :(得分:4)

我认为你不能直接在C ++ 11中做到这一点(参见@ Nawaz的评论以获得解决方法)。但是,C ++ 14在此实例中通过generalized lambda captures

完全有帮助
auto px = [v = this->z]() // capture by value just ONE member variable
{ 
        std::cout << v << std::endl;
};

示例:

#include <functional>
#include <iostream>

struct myclass {
    myclass(): z{} {}
    myclass(int qx): z(qx) {   }
    std::function<void()> create() {
        auto px = [v = this->z]() {
            std::cout << v << std::endl;
        };
        return px;
    }
    int z;
};

int main()
{
    myclass my;
    my.z = 2;
    auto func = my.create();
    func();
    my.z = 3;
    func();
}

Live on Coliru

答案 1 :(得分:2)

Lambdas只能捕获声明它们的本地范围的成员。他们无法通过复制或引用来捕获成员变量。

但是,C ++ 14的广义lambda捕获可以完成工作:

auto px = [z = z](){
    std::cout << z << std::endl;
};

您可以使用z限定内部this->z,以明确您正在做的事情。

如果C ++ 14不可用,您可以通过在函数中创建临时变量来显式捕获,该变量将被捕获:

auto z = this->z;
auto px = [z](){
    std::cout << z << std::endl;
};