Это хорошее время, чтобы узнать, что такое xvalues и glvalues .
Rvalues может быть двух типов - prvalues и xvalues . Согласно новому стандарту C ++ 17
A prvalue - это выражение, вычисление которого инициализирует объект, битовое поле или операнд оператора, как определено контекстом, в котором он появляется.
поэтому что-то вроде fun()
в вашем примере оценивается как prvalue (которое является rvalue). Это также говорит нам, что fun().v
не является prvalue, так как это не ванильная инициализация.
Xvalues , которые также являются rvalues, определяются так
xvalue (значение "eXpiring") также относится к объекту, обычно ближе к концу его времени жизни (так что его ресурсы могут быть перемещены, например). Определенные виды выражений, включающие ссылки на rvalue (8.3.2), дают значения xvalue. [Пример: Результатом вызова функции, возвращаемый тип которой является rvalue-ссылкой на тип объекта, является xvalue (5.2.2). - конец примера]
Помимо значений rval, еще одной зонтичной категорией значений является glvalue двух типов: xvalues и традиционные lvalues .
На данный момент мы определили категории основных значений. Это можно представить так:
![enter image description here](https://i.stack.imgur.com/VNVwl.png)
Категория glvalue в широком смысле может означать то, что lvalues должно было означать до того, как семантика перемещения стала вещью - вещью, которая может быть в левой части выражения , glvalue означает обобщенное lvalue.
Если мы посмотрим на определение xvalue , то оно говорит, что что-то является xvalue , если оно подходит к концу своего срока жизни. В вашем примере fun().v
подходит к концу своего срока службы. Таким образом, его ресурсы могут быть перемещены. А поскольку его ресурсы можно перемещать, это не lvalue, поэтому ваше выражение вписывается в единственную оставшуюся категорию значений листа - xvalue .