How can a std::reference_wrapper to a rvalue lambda work?
c++, c++11, lambda
Solution
OK, let's start with the basics: the above code is certainly not legal because it is ill-formed in some rather basic ways. The line
std::function<bool(int)> f(std::cref([n](int i) {return i%n == 0));
would at bare minimum need to be written as
std::function<bool(int)> f(std::cref([n](int i) {return i%n == 0;}));
Note that the code was written in the Dr.Dobb's article as it was in the question, i.e., any statement of the code being legal is already quite questionable.
Once the simple syntax errors are resolved the next question is whether `std::cref()` can actually be used to bind to an rvalue. The lambda exrpession is clearly a temporary according to 5.1.2 [expr.prim.lambda] paragraph 2 (thanks to DyP for the reference). Since it would generally be a rather bad idea to bind a reference to a temporary and is prohibited elsewhere, `std::cref()` would be a way to circumvent this restriction. It turns out that according to 20.10 [function.objects] paragraph 2 `std::cref()` is declared as
template <class T> reference_wrapper<const T> cref(const T&) noexcept;
template <class T> void cref(const T&&) = delete;
template <class T> reference_wrapper<const T> cref(reference_wrapper<T>) noexcept;
That is, the statement is incorrect even after correcting the syntax errors. Neither gcc nor clang compile this code (I have used fairly recent versions of both compilers with their respective standard C++ libraries). That is, based on the above declaration this code is clearly illegal!
Finally, there is nothing which would extend the life-time of the temporary in the above expression. The only reason the life-time of a temporary is extended is when it or one of its data members is immediately bound to a [`const`] reference. Wrapping a function call around the temporary inhibits this life-time extensions.
In summary: the code quoted in the article is not legal on many different levels!
Problem
In this article it says the following code is valid C++11 and works with GNU's libstdc++: ``` int n; std::vector<int> v; ... std::function<bool(int)> f(std::cref([n](int i) {return i%n == 0)); std::count_if(v.begin(), v.end(), f); ``` The thing is that I aways believed the lambda object to be created at call site, what would make it a temporary object in this snippet, since it is not being stored on any variable, but instead a `const` reference to it is being created and passed to the `std::function`. If that is so, the lambda object should have been destroyed right alway, leaving a dangling reference inside `f`, that would lead to undefined behavior when used by `std::count_if`. Assuming the article is not wrong, what is wrong about my mental model? When the lambda object is destructed?