4

I've read few papers about && and I'm just curious if having:

void fnc_1(int&& p)
{
//...
}

void fnc(int&& r)
{
fnc_1(r);//am I suppose to/should I? call it like so:fnc_1(std::forward(r)) 
}

or just passing 'r' is enough?

Alok Save
  • 202,538
  • 53
  • 430
  • 533
smallB
  • 16,662
  • 33
  • 107
  • 151

2 Answers2

6

fnc_1(r) won't compile, because r is an lvalue, just like any other variable, regardless of type. Yes, that's right, named rvalue references are lvalues, not rvalues.

fnc_1(std::forward(r)) also won't compile, because std::forward is specifically designed not to infer its template argument.

To pass an rvalue, either of the following would work:

fnc_1(std::move(r))
fnc_1(std::forward<int&&>(r))  
fnc_1(std::forward<int>(r))  

Using std::move is the idiomatic way to cast an lvalue to an rvalue, so I would recommend using that.

fredoverflow
  • 256,549
  • 94
  • 388
  • 662
3

The std::forward template is usually for dependent types. Please read this question carefully to see whether it applies here. This is a difficult subject to master, so feel free to update your question with relevant details about your exact problem (using rvalue references for integers isn't terribly exciting...).

I believe your question is about the understanding of the basic properties of rvalue references. The rule of thumb to remember is:

  • whatever has a name is a lvalue (const or not).
  • whatever has no name is a rvalue.
  • Types with && bind to rvalues.

If you have a function...

void foo(SomeClass&& x)
{
    // ... then here x has type SomeClass& !
}

then inside the body, x is a name, and therefore a l value. It really has type SomeClass&. You must use std::move to turn a SomeClass& into SomeClass&&:

void bar(SomeClass&& x)
{
    // Since `x` has a name here, it is a Lvalue.
    // Therefore it has type SomeClass&, what the signature doesn't indicate.

    // We thus have to explicitly turn it into a rvalue:
    foo(std::move(x));
}
Community
  • 1
  • 1
Alexandre C.
  • 55,948
  • 11
  • 128
  • 197
  • Isn't the program is ill formed because reference to a reference is not allowed in C++? – Alok Save Jul 28 '11 at 16:55
  • @Alex I've typed int just as an example, in my code it is a class template – smallB Jul 28 '11 at 16:57
  • @Als: this is not a reference to reference, it is a *rvalue reference* (something from the future C++ standard). – Alexandre C. Jul 28 '11 at 16:58
  • @Alexandre C.: Aha! Thanks..I missed that, Also the Q was never tagged, `C++0x`, I shall do that now. – Alok Save Jul 28 '11 at 16:59
  • 1
    @smallB: please see http://stackoverflow.com/questions/3582001/advantages-of-using-forward and discuss what you don't understand. There is a lot of quite difficult things to grasp before using rvalue references and perfect forwarding. – Alexandre C. Jul 28 '11 at 17:00
  • @Alexandre I think you meant `void bar(SomeClass & x)` to illustrate how `std::move()` creates an rvalue-ref from a ref. – Richard Jul 28 '11 at 17:36
  • @Richard: inside the body of `bar`, `x` has type `SomeClass&`, not `SomeClass&&`. This is the first thing to remember about rvalue references. Let me clarify this point in the answer's body. – Alexandre C. Jul 28 '11 at 18:03