I'm passing a lambda to a function which accepts it as a r-value reference.
If my lambda is defined in the function-call itself, I don't really care what happens to it later.
But if my lambda is a variable (say I want to use it more than once) I do want to know that it is not moved-from.
Is there a way to know will it be moved-from or not, making it unusable or usable accordingly after the call has returned?
EDIT:
Just to clarify, the lambda doesn't capture anything. What I care about is the functor itself: auto fn = [](int a){ return a; };
Let me make it even harder. I'll pass the functor as rvalue: std::move(fn)
std::move is only a cast. It does not move anything but the rvalue argument in the callee now binds to proper rvalue.
The question is, is fn
guaranteed to get moved? Is it guaranteed to not get moved? Is there any guarantee at all? Can I make it behave this way or that way or is it up to the callee?
I want to know because I want to know can I pass fn
as a function parameter twice.
EDIT #2:
Let's take another case. I have to call a function with a container. Vector, map, or whatever else. The function signature says &&
.
I can wrap my container with std move or std forward to get an rvalue ref into the callee. It's really the same thing as they are both just glorified casts.
Now, let's say I used std forward because I really like my container to not go anywhere.
I can easily see the callee not being aware of my intention and move my container making it invalid (gutted) after the call. Is this a language defect or am i missing something?
An rvalue reference is formed by placing an && after some type. An rvalue reference behaves just like an lvalue reference except that it can bind to a temporary (an rvalue), whereas you can not bind a (non const) lvalue reference to an rvalue.
“r-value” refers to the data value that is stored at some address in memory. References in C++ are nothing but the alternative to the already existing variable. They are declared using the '&' before the name of the variable.
Introducing the magic of rvalue references C++0x has introduced a new type called rvalue reference, denoted by placing a double ampersand && after some type. Such rvalue reference lets you modify the value of a temporary object: it's like removing the const attribute in the second line above!
Move semantics allows you to avoid unnecessary copies when working with temporary objects that are about to evaporate, and whose resources can safely be taken from that temporary object and used by another.
Well, if the function accept a universal reference and you want to forbid moving, there are many options for you to choose from, among others:
std::as_const()
to simplify that).Of course, unless the lambda captures locals by value which have different move-semantics than copy-semantics, and the called function actually takes advantage of that, the point is moot.
Will it actually take the opportunity?
Examine the contract, and then simply trust in it or try to verify the implementation. There is no shortcut.
Let's not even mention that C++ allows the programmer to explicitly opt out of the (limited) safety it provides.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With