4

I have seen many answers on SO asking about capturing this by reference but I have a different question. What if I want to capture a specific variable owned by this object?

For example:

auto rel_pose = [this->_last_pose["main_pose"],&pose](Eigen::VectorXd pose1, Eigen::VectorXd pose2)
    {
        // Some code
        return pose;
    };

I want to capture the specific variable of this by value and use it inside my lambda expression. Why this is not possible?

3 Answers 3

5

You can apply by-copy capture with an initializer (since C++14) (or by-reference capture with an initializer, depends on your demand), e.g.

auto rel_pose = [some_pose = this->_last_pose["main_pose"], &pose](Eigen::VectorXd pose1, Eigen::VectorXd pose2)
{
    // Some code using some_pose
    return pose;
};

Note that we can only capture identifiers in lambda, we can't capture expressions like this->_last_pose["main_pose"] directly. The captures with an initializer just solve such issues straightforward.

Sign up to request clarification or add additional context in comments.

9 Comments

Why is that we need to copy the object's variable in order to capture it? Just a C++ rule?
@Edmund We don't need to copy it. We can use references.
@Edmund ??? You said "want to capture the specific variable of this by value".. You can capture by reference too.
@songyuanyao I mean the assignment operation, what does it represent in the capture brackets?
@Edmund So whenever we want to pass some object's variable in lambda we need to initialize a new variable for that How would the alternative even work? What you specify in the example is more than "an object's variable", it's a whole expression that involves the object. You can't just put that in the capture and somehow expect the body of the lambda to recognize the same arbitrary expression when found in the lambda body, and automatically transform it into the captured reference. Especially as especially as arbitrary expressions can differ in subtle ways.
|
5

It's possible:

struct S
{
    int i = 7;
    char c = 0;
};

int main(int argc, char* argv[])
{
    S s;
    auto l = [integer = s.i]() {
        return integer;
    };

    return l();
}

1 Comment

Why is that we need to copy the object's variable in order to capture it? Just a C++ rule?
0

Why this is not possible?

It's possible, like other answers show. But you must do it explicitly. Accessing any member of the current object in the lambda is transformed automatically to an access through the this pointer. When you write a plain [this->_last_pose["main_pose"],&pose], what's really captured is this, and the access to _last_pose goes through it.

It's simply how lambda captures are specified for member variables. Be grateful you are compiling C++14. In C++11 capturing members by value was not as easy as adding an init capture that does an copy.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.