2

Can someone give me an "acyclic" definition/explanation of xvalue and std::move() behaviour?

I looked on cppreference page, and it says "std::move() produces an xvalue". (Ok)

Then I looked for "xvalue"'s definition and the first thing it says is it's a function call or overloaded operator expression, such as "std:move". (???)

One Two Three
  • 22,327
  • 24
  • 73
  • 114

2 Answers2

3

std::move() converts an expression from being an lvalue or rvalue to being an xvalue.

An lvalue is an object occupies some location in memory while an rvalue occupies memory temporarily.

int main() {  
   int x = 3 + 4;  
   std::cout << x << std::endl;
}

In the example above, the x is an lvalue and the 3 + 4 is an rvalue. Now see the x is not temporary while 3 + 4 expression is a temporary value.

Now consider that you do this: int y = x;. You have two copies of that x in the memory right?

Check the example below:

swap(int &a, int &b) {
    int tmp = a;   // Two copies of a; one of them is tmp
    a = b;      // Two copies of b; one of them is a
    b = tmp;    // Two copies of tmp; one of them is b
}

Check the below example using std::move():

swap(int &a, int &b) {
    int tmp = std::move(a); // tmp is an xvalue
    a = std::move(b);   
    b = std::move(tmp);
}

You don't copy; you move them somewhere instead. Actually, you transfer the content of it for some time. They are going to be destroyed soon. They are now xvalues :)

Onur Tuna
  • 1,030
  • 1
  • 10
  • 28
  • 7
    In the second version of swap, tmp is an lvalue. The rhs of each of those three statements is an xvalue produced from an lvalue by std::move. – Don Slowik Jul 09 '20 at 14:11
1

There is no cyclic definition in that sentence.

The following expressions are xvalue expressions:

a function call or an overloaded operator expression, whose return type is rvalue reference to object, such as std::move(x);

...

Here std::move is merely an example, the essence is "whose return type is rvalue reference". Since a function returning rvalue reference is not very usual, while std::move is aimed to do so, thus it serves a good example. This is the signature of std::move:

template< class T >
constexpr typename std::remove_reference<T>::type&& move( T&& t ) noexcept;

whose return value must be an rvalue reference.

Community
  • 1
  • 1
llllllllll
  • 16,169
  • 4
  • 31
  • 54