Search code examples
c++11value-categories

What do they mean by having identity but not movable for Lvalue in C++ 11?


I am now studying C++ 11 and getting confused by value category of expressions in C++ 11. According to terminology the Lvalue is the top-left point of the W, that is iM (or i-m sometimes) meaning that "has identity but cannot be moved from". This really makes me confused. Please consider the example below:

#include <iostream>

int main()
{
    int a = 0, b = 1, c = 2;
    a = std::move(b = c);
    std::cout << a << '\n';
}

This example compiled well.

We all know that the assignment b = c is an Lvalue then what do they mean by 'cannot be moved from'? Please give examples that can clearly illustrate this!

Thanks!


Solution

  • Roughly speaking:

    • an lvalue has identity because you can take its address

      int x;
      &x; // ok
      
    • an lvalue cannot be moved from because it cannot be used as an argument to move constructor/assignment

      struct Foo 
      {
          Foo(Foo&);  // 0
          Foo(Foo&&); // 1
      };
      
      Foo x;
      Foo y{x}; // calls 0, not 1
      

      in the example above, x is an lvalue: the copy constructor is invoked. If you want to move from x, you need to make it an rvalue: this is why you must use std::move(x) to cast it to an rvalue reference.

      Foo y{std::move(x)}; // calls 1
      

    In your example std::move(b = c) is an rvalue, as std::move is literally just a static_cast to an rvalue reference.