How do I know if object passed as r-value will get moved?
Asked Answered
B

1

6

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?

Barnsley answered 4/11, 2018 at 21:47 Comment(2)
Does the lambda capture some variables that have different move semantics compared to their copy semantics?Warwick
If it's a variable, it's an lvalue and won't bind to an rvalue reference. Unclear what you're asking. Pls provide an example.Bolometer
L
3

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:

  1. Pass by constant reference (C++17 has std::as_const() to simplify that).
  2. Save it as a local and don't convert to rvalue-reference. Seems you do that.
  3. Use something to explicitly convert an rvalue-reference to an lvalue-reference.

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.

Lilia answered 4/11, 2018 at 21:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.