9

I've encountered a notation like:

int x = 4;
auto y = [&r = x, x = x+1]()->int { 
    r += 2;
    return x+2;
}();

Can you explain this statement? I was a user of C++03 and recently upgraded to C++11. From today I starts C++14 and encountered this snippet.

Thanks!

Kaidul
  • 14,015
  • 11
  • 68
  • 139
  • 3
    http://en.wikipedia.org/wiki/C%2B%2B14#Lambda_captures_expressions. There's also a [proposal](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3610.html) you can look at. – chris Aug 20 '14 at 15:05
  • Wow, this syntax is messed up. – Quentin Aug 20 '14 at 15:15
  • 3
    I'm not sure how this question will ever help anyone else. It's not exactly searchable... – Lightness Races in Orbit Aug 20 '14 at 15:15
  • 1
    @LightnessRacesinOrbit If you think the question need a edit to be searchable (adding searchable keywords), you can edit it. – Kaidul Aug 20 '14 at 15:23
  • 2
    @KaidulIslam: No, you're the only one who can further explain what part of the code confuses you. Besides, it's _your_ responsibility to post a good question! – Lightness Races in Orbit Aug 20 '14 at 15:26
  • 4
    Not sure why this question is being downvoted. Not everyone knows about all the new features C++14 is going to have. – jliv902 Aug 20 '14 at 15:51

2 Answers2

8

Thanks @chris for the wikipedia reference. What I found is -

Here is nice explanation who don't know about the old lambda Captures of C++11

In C++14:


C++11 lambda functions capture variables declared in their outer scope by value-copy or by reference. This means that value members of a lambda cannot be move-only types. C++14 allows captured members to be initialized with arbitrary expressions. This allows both capture by value-move and declaring arbitrary members of the lambda, without having a correspondingly named variable in an outer scope.

This is done via the use of an initializer expression:

auto lambda = [value = 1] {return value;};

The lambda function lambda will return 1, which is what value was initialized with. The declared capture deduces the type from the initializer expression as if by auto.

This can be used to capture by move, via the use of the standard std::move function:

std::unique_ptr<int> ptr(new int(10));
auto lambda = [value = std::move(ptr)] {return *value;};

So the above expression updates x to 6, and initializes y to 7.

Community
  • 1
  • 1
Kaidul
  • 14,015
  • 11
  • 68
  • 139
  • I wouldn't say `y` is initialized with `7` since it is a lambda function. – tgmath Aug 20 '14 at 15:57
  • The lambda is immediately evaluated though, so `y` is initialised. – Ben Hymers Aug 20 '14 at 17:41
  • If anyone want to give a detailed explanation, please post an answer. I won't accept this answer iff anyone can give some more intuition (as this is my own answer) – Kaidul Aug 20 '14 at 17:43
1

This example is part of C++14 feature "Lambda capture Initializers", This allows creating lambda captures initialized with arbitrary expressions. Using this reference-captures can have different names than the referenced variable.

If you run your code :

int x = 4;
auto y = [&r = x, x = x+1]()->int { 
    r += 2; //r=6
    return x+2;//5+2
};
cout<<y()<<endl; // this will print 7
Ramanand Yadav
  • 127
  • 1
  • 3