Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

Is this lambda recursion valid?

#include <functional>
#include <iostream>

int main() {
   std::function<int(int)> g = [&g](int k) {
       return (k ? k * g(k-1) : 1);
   };

   std::cout << g(10); // 3628800
}

It appears to compile and run ok, but I'm nervous about closing over g in the same statement that I initialise it. Strict validity on a scale of 1-10...?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
157 views
Welcome To Ask or Share your Answers For Others

1 Answer

At the point at which you capture g by reference, it has been declared, so the name is available for use:

3.3.2/1 The point of declaration for a name is immediately after its complete declarator (Clause 8) and before its initializer

You are allowed to use objects in limited ways before they are initialised - basically, anything that doesn't depend on the value is OK:

3.8/6 before the lifetime of an object has started but after the storage which the object will occupy has been allocated [...] any glvalue that refers to the original object may be used but only in limited ways. [...] using the properties of the glvalue that do not depend on its value is well-defined.

So by my understanding, what you are doing is well-defined.

(Although, being ultrapedantic, I don't think it's specified when the storage for an automatic object is allocated, and 8.3.2/5 says that "a reference shall be initialized to refer to a valid object" without defining "valid", so there's scope to argue that it's not well-defined).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share

548k questions

547k answers

4 comments

86.3k users

...