17

Given

void foo( int&& x ) {

    std::cout << &x;
}

This works but what does this address actually represent? Is a temporary int created when foo is called and that is what the address represents? If this is true and if I write int y = 5; foo(static_cast<int&&>(y));, does this cause another temporary to be created or will the compiler intelligently refer to y?

edaniels
  • 708
  • 5
  • 23
  • Doesn't have to be temporary. Nothing stops you from doing `int x = 42; foo(x);` – Igor Tandetnik Oct 14 '14 at 23:51
  • 1
    FWIW, your cast is simply `std::move(y)`. – chris Oct 14 '14 at 23:51
  • 4
    @IgorTandetnik, That won't compile because rvalue references don't bind to lvalues. – chris Oct 14 '14 at 23:52
  • 1
    @chris I know but I just wanted to explicitly state I am creating an rvalue reference since std::move doesn't have the best name – edaniels Oct 14 '14 at 23:52
  • @chris Right. Silly me. Never mind. – Igor Tandetnik Oct 14 '14 at 23:54
  • 6
    An rvalue doesn't have to be a temporary. Temporaries are prvalues, but not all rvalues are temporaries. The key feature of an object that is bound to an rvalue reference is that there is not supposed to be any other alias of the object. (This isn't enforced by the type system, but this is how you are supposed to use it.) – Kerrek SB Oct 15 '14 at 00:03
  • possible duplicate of [What are move semantics?](http://stackoverflow.com/questions/3106110/what-are-move-semantics) – Decipher Oct 15 '14 at 00:21

1 Answers1

13

When you take an address of an rvalue reference, it returns a pointer to the object that reference is bound to, like with lvalue references. The object can be a temporary or not (if for example you cast an lvalue to rvalue reference like you do in your code).

int y = 5; foo(static_cast<int&&>(y)); does not create a temporary. This conversion is described in part 5.2.9/3 of the standard:

A glvalue, class prvalue, or array prvalue of type “cv1 T1” can be cast to type “rvalue reference to cv2 T2” if “cv2 T2” is reference-compatible with “cv1 T1”.

A temporary will be created if for example you call foo(1);.

Anton Savin
  • 40,838
  • 8
  • 54
  • 90
  • When speaking about rvalues, I prefer to use the term "anonymous variables" instead of "temporal objects". So, verbosity is reduced: «std::move made the object anonymous", and `int&& x` binds to anonymous integers. – ABu Oct 15 '14 at 00:23
  • 3
    @Peregring-lk you can do it if you write your own blog post or speaking with people you know for a long time, or you should refer to some source, because there's no definition of "anonymous object" in the C++ standard. When answering here I think it's better to operate the terms everyone knows or at least can look up in a well known place. – Anton Savin Oct 15 '14 at 00:31