I have 3 questions:
-
Can I bind a lvalue directly to a rvalue reference?
-
What happens to the object that being
std::move()? -
What’s the difference between std::move and
std::forward?
struct myStr{
int m_i;
};
void foo(myStr&& rs) { }
myStr rValueGene()
{
return myStr();
}
int main()
{
myStr mS= {1};
foo(rValueGene()); //ok passing in modifiable rvalue to rvalue reference
// To Question 1:
//below initilize rvalue reference with modifiable lvalue, should be ok
//but VS2010 gives a compile error: error C2440: 'initializing' : cannot convert from 'myStr' to 'myStr &&'
//Is this correct ?
myStr&& rvalueRef = mS;
//by using std::move it seems ok, is this the standard way of doing this
//to pass a lvalue to rvalue reference
//myStr&& rvalueRef = std::move(mS);
// To Question 2:
//also what happens to mS object after std::move ?
//destroyed , undefined ?
}
Not without an explicit cast (ie:
std::move).Nothing until it is actually moved. All
std::movedoes is return an r-value reference to what you gave it. The actual moving happens in the move constructor/assignment of the type in question.std::moveis for moving;std::forwardis for forwarding. That sounds glib, but that’s the idea. If you are intending for an object to be moved, then you usestd::move. If you are intending for an object to be forwarded, you usestd::forward.Forwarding uses specialized semantics that allow conversions between types of references, so that the reference natures are preserved between calls. The specifics of all of this are very… technical.
std::movealways returns a &&. If you give it an l-value reference, it returns an r-value reference. If you give it a value type, it returns an r-value reference to that value. And so forth.std::forwarddoes not always return a &&. Syntactically,std::forwardis just doing astatic_cast<T&&>. However, because of specialized syntax around casting to && types, this cast does not always return a &&. Yes, that’s weird, but it solves the forwarding problem, so nobody cares. That’s why it’s contained instd::forward, rather than having to explicitly do thestatic_castyourself.