c++value-categoriesxvalueprvalue

How expressions designating temporary objects are xvalue expression?


From cppreference, I am trying to understand expressions that yield xvalues, and I ended up with this summary:

The following expressions are xvalue expressions:

  • ...
  • any expression that designates a temporary object, after temporary materialization.

Temporary materialization is:

A prvalue of any complete type T can be converted to an xvalue of the same type T. This conversion initializes a temporary object of type T from the prvalue by evaluating the prvalue with the temporary object as its result object, and produces an xvalue denoting the temporary object.

And per my understanding from the above quote, temporary materialization involves converting the prvalue into an xvalue to initialize the created temporary; and that's mean that whenever prvalue is materialized, an xvalue expression appears. So I found myself have to understand when exactly a prvalue is materialized. then I have checked this from cppreference:

Temporary materialization occurs in the following situations:

  • 1- when binding a reference to a prvalue;
  • 2- when performing a member access on a class prvalue;
  • 3- when performing an array-to-pointer conversion or subscripting on an array prvalue;
  • 4- when initializing an object of type std::initializer_list from a braced-init-list;
  • 5- when typeid is applied to a prvalue
  • 6- when sizeof is applied to a prvalue
  • 7- when a prvalue appears as a discarded-value expression.

Note that temporary materialization does not occur when initializing an object from a prvalue of the same type (by direct-initialization or copy-initialization): such object is initialized directly from the initializer. This ensures "guaranteed copy elision".

Can anyone help me with simple examples how xvalue expression are involved in the situation 3, 4 and 7.


Solution

  • situation 3, 4 and 7.

    7 (discarded expression) is the easiest:

    42; // materialize and discard
    std::string{"abc"}; // materialize and discard
    

    3 (doing things to array rvalue) requires knowing how to make them

    using arr_t = int[2][3];
    int a = arr_t{}[0][0]; // have to materialize to be able to subscript
    

    4 (making an std::initializer_list) is what it says on the tin

    std::initializer_list<std::string>{
      "abc"s,
      "def"s
    }; // have to materialize the two strings
       // to place them in the secret array pointed to by the list