В разделе 5, в котором описывается синтаксис допустимых выражений, перечислены для каждого синтаксиса выражения условия, в которых выражение является lvalue, xvalue или prvalue. Полный список возможных значений x из раздела 5:
5.2.2 параграф 10: вызов функции - это ... значение x, если тип результата является ссылкой rvalue на тип объекта.
(На техническом языке Стандарта «тип объекта» не означает то же самое, что «тип класса». «Тип объекта» включает основные типы, указатели и массивы и исключает только типы функций. Ссылка rvalue на тип функции всегда рассматривается как lvalue, а не как xvalue.)
Наиболее заметными функциями, которые возвращают ссылку на rvalue, являются, конечно, std::move
, а иногда и std::forward
.
5.2.5 абзац 4: Если E2
является нестатическим элементом данных ... если E1
является значением x, тогда E1.E2
является значением x
(С другой стороны, поиск элемента данных E1->E2
всегда является lvalue.)
Точно так же, если E1
является значением x, тогда поиск элемента данных E1.*E2
является значением x:
5.5 абзац 6. Результат выражения .*
, второй операнд которого является указателем на элемент данных, имеет ту же категорию значений (3.10), что и его первый операнд.
Для различных типов слепков:
dynamic_cast<Type>(expr)
: 5.2.7 параграф 2
static_cast<Type>(expr)
: 5.2.9 абзац 1
reinterpret_cast<Type>(expr)
: 5.2.10 параграф 1
const_cast<Type>(expr)
: 5.2.11 абзац 1
(Type) expr
: 5.4 абзац 1
выражение является значением x тогда и только тогда, когда Type
является ссылкой rvalue на тип объекта. То же верно и для Type(expr)
, поскольку
5.2.3 абзац 1: Если список выражений [в скобках после имени типа] является единственным выражением, выражение преобразования типа эквивалентно (по определенности и, если определено по смыслу) соответствующему выражению приведения (5.4).
(С другой стороны, Type{expr}
всегда является prvalue.)
Раздел 5.16 об условном операторе заканчивается тем, что A ? B : C
иногда может быть значением x, если B и / или C являются значениями x. Но полные правила сложно резюмировать.
Если выражение заканчивается вызовом определяемой пользователем перегруженной операторной функции, то раздел 5.2.2 применяется к этому выражению, а не к тому, которое описывает поведение встроенного оператора. (См. Выражение a + a
в опубликованном примере @James.)
person
aschepler
schedule
26.07.2012