The unary * operator performs indirection:
the expression to which it is applied shall be a pointer to an object
type, or a pointer to a function type and the result is an lvalue
referring to the object or function to which the expression points.
If
the type of the expression is “pointer to T”, the type of the
result is “T”.
Indirection through a pointer to an incomplete type (other than
cvvoid) is valid.
The lvalue thus obtained can be
used in limited ways (to initialize a reference, for example); this
lvalue must not be converted to a prvalue, see [conv.lval].
If the operand is a qualified-id naming a non-static or variant member m
of some class C with type T, the result has type “pointer to member
of class C of type T” and is a prvalue designating C::m.
Otherwise, if the operand is an lvalue of type T,
the resulting expression is a prvalue of type “pointer to T”
whose result is a pointer to the designated object ([intro.memory]) or function.
[Example 1: struct A {int i; };
struct B : A {};
...&B::i ...// has type int A::*int a;
int* p1 =&a;
int* p2 = p1 +1; // defined behaviorbool b = p2 > p1; // defined behavior, with value true — end example]
A pointer to member formed from a mutable non-static data
member ([dcl.stc]) does not reflect the mutable specifier
associated with the non-static data member.
That is, the expression &(qualified-id), where the
qualified-id is enclosed in parentheses, does not form an
expression of type “pointer to member”.
Neither does
qualified-id, because there is no implicit conversion from a
qualified-id for a non-static member function to the type
“pointer to member function” as there is from an lvalue of function
type to the type “pointer to function” ([conv.func]).
Nor is
&unqualified-id a pointer to member, even within the scope of
the unqualified-id's class.
If & is applied to an lvalue of incomplete class type and the
complete type declares operator&(), it is unspecified whether
the operator has the built-in meaning or the operator function is
called.
The address of an overloaded function can be taken
only in a context that uniquely determines which version of the
overloaded function is referred to (see [over.over]).
Since the context might determine whether the operand is a static or
non-static member function, the context can also affect whether the
expression has type “pointer to function” or “pointer to member
function”.
The operand of the logical negation operator ! is
contextually converted to bool;
its value is true
if the converted operand is false and false otherwise.
Because the grammar does not permit an operator to follow the
., ->, or :: tokens, a ~ followed by
a type-name or decltype-specifier in a
member access expression or qualified-id is
unambiguously parsed as a destructor name.