Если вы просто хотите получить быстрый и обычно правильный ответ, примите во внимание следующие правила:
- Если это функция или уже существующий объект, то это glvalue.
- Большинство glvalues являются lvalues.
- xvalue - это то, что может быть конкретно перемещено: приведение к ссылочному типу rvalue или вызов функции, где возвращаемый тип функции является ссылочным типом rvalue (особенно
std::move
и иногда std::forward
).
- Если это просто значение или способ создания нового объекта, тогда это значение.
Но есть некоторые случаи, когда категория все еще может быть неясной. И вышеупомянутое включает некоторые упрощения (в частности, правила для A.B
и A ? B : C
являются более сложными).
Единственный действительно надежный способ - найти ваш ответ в Стандарте.
Определите, какое у вас выражение с точки зрения грамматики. Буквальный? Выражение оператора? Лямбда? Etc.
Если выражение является операторным выражением, выясните, выберет ли разрешение перегрузки некоторую перегруженную операторную функцию или встроенный оператор-кандидат, как описано в [over.match.oper] , [over.oper] и [over.built] .
Если выражение на самом деле является вызовом перегруженной операторной функции, категория значения определяется по типу возврата операторской функции, выбранной разрешением перегрузки, как описано в [expr.call] * 1042. *. В этом случае игнорируйте описание поведения встроенного оператора для этой цели.
В противном случае найдите раздел [expr.prim] или [expr.compound] (см. оглавление ) для грамматической формы выражения. В этом разделе будет указано, как определяется категория значения выражения. Часто бывает необходимо знать типы и категории значений любых подвыражений, поэтому вам может потребоваться рекурсивно следовать этим правилам.