cpp/language/decltype

Inspects the declared type of an entity or the type and value category of an expression.

Explanation
@1@ If the argument is an unparenthesized or an unparenthesized  expression, then decltype yields the type of the  named by this expression. If there is no such entity, or if the argument names a set of overloaded functions, the program is ill-formed.

@2@ If the argument is any other expression of type, and
 * @a@ if the of  is, then decltype yields ;
 * @b@ if the value category of is, then decltype yields ;
 * @c@ if the value category of is, then decltype yields.

Because no temporary object is created, the type need not be or have an available, and can be. This rule doesn't apply to sub-expressions: in, must have a complete type, but  need not.

Note that if the name of an object is parenthesized, it is treated as an ordinary lvalue expression, thus and  are often different types.

is useful when declaring types that are difficult or impossible to declare using standard notation, like lambda-related types or types that depend on template parameters.