Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's a good way to capture member variable by value in c++11? [duplicate]

Tags:

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();

This code will compile in gcc 4.6.3, which will do the correct thing to make a copy of member variable z, and both print will get 2. In gcc 4.8.2 this doesn't compile anymore..

error: 'this' was not captured for this lambda function

I wonder why this functionality was removed as it was quite useful.

like image 946
user40129 Avatar asked Feb 05 '16 18:02

user40129


People also ask

How do you capture a member variable?

To capture the member variables inside lambda function, capture the “this” pointer by value i.e. std::for_each(vec. begin(), vec. end(), [this](int element){ //.... }

What is the correct syntax for lambda expression in C++11?

Lambdas can both capture variables and accept input parameters. A parameter list (lambda declarator in the Standard syntax) is optional and in most aspects resembles the parameter list for a function. auto y = [] (int first, int second) { return first + second; };

How do you capture a variable in lambda function?

Much like functions can change the value of arguments passed by reference, we can also capture variables by reference to allow our lambda to affect the value of the argument. To capture a variable by reference, we prepend an ampersand ( & ) to the variable name in the capture.

What is a lambda capture list?

The capture list defines the outside variables that are accessible from within the lambda function body. The only capture defaults are. & (implicitly capture the used automatic variables by reference) and. = (implicitly capture the used automatic variables by copy).


1 Answers

I don't think you can do this directly in C++11 (see @Nawaz's comment for a workaround). However, C++14 helps exactly in this instance, via generalized lambda captures:

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

Example:

#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

like image 134
vsoftco Avatar answered Nov 11 '22 13:11

vsoftco