You usually only need to know whether something is an lvalue or an rvalue. These two categories of expressions are distinct from one another.
It is usually the case that an lvalue expression refers to something that is going to hang around for a while. For example, a variable name is an lvalue because variables stick around. On the other hand, rvalue expressions usually refer to something that is only existing temporarily. You can only take the address of an lvalue because why on earth would you need the address of something that was going to disappear soon?
Now, when making this distinction, you have to take into account what the compiler knows at the time. For example, take the function void foo(const A& a)
. Inside this function, the compiler doesn't know if the object passed was a temporary object or not, so it just assumes that it will stick around. That is, a
is an lvalue. Even though you can happily pass a temporary object into this function (call it with an rvalue expression), the expression a
is still an lvalue.
Taking this into account, you can further remember whether something is an lvalue or an rvalue by whether it is named. In the above example, since the object gets named as a
, it is an lvalue.
Now, for the rest of the categories, you should remember the following diagram:

Note that lvalues and rvalues are indeed distinct. However, rvalues are split up into two other categories, xvalues and prvalues. Also, xvalues are also considered to be glvalues along with all the lvalue expressions.
Now knowing when these show up comes down to remembering a few cases.
xvalues are not very common. They only show up in situations involving conversions to rvalue references. Here are all of the cases:
- result of a function that returns an rvalue reference
- a cast to an rvalue refernece
object.x
if object
is an xvalue
object.*member
if pobject
is an xvalue
By definition, prvalues are every other type of rvalue that is not an xvalue. For example, returning an object by value from a function creates a temporary returned object. The expression denoting that object is a prvalue.
The category glvalue is used to refer to everything that is not an prvalue.