cpp/language/operator member access

Accesses a member of its operand.

Explanation
Built-in subscript operator provides access to an object pointed-to by the or  operand.

Built-in indirection operator provides access to an object or function pointed-to by the pointer operand.

Built-in address-of operator creates a pointer pointing to the object or function operand.

Member of object and pointer to member of object operators provide access to a data member or member function of the object operand.

Built-in member of pointer and pointer to member of pointer operators provide access to a data member or member function of the class pointed-to by the pointer operand.

Built-in subscript operator
The subscript operator expressions have the form

@1@ For the built-in operator, one of the expressions (either or ) must be a glvalue of type “array of ” or a prvalue of type “pointer to ”, while the other expression ( or, respectively) must be a prvalue of unscoped enumeration or integral type. The result of this expression has the type. @2@ The form with brace-enclosed list inside the square brackets is only used to call an overloaded. @3@ The form with comma-separated expression list inside the square brackets is only used to call an overloaded.

The built-in subscript expression is exactly identical to the expression  except for its value category (see below) : the pointer operand (which may be a result of array-to-pointer conversion, and which must point to an element of some array or one past the end) is adjusted to point to another element of the same array, following the rules of, and is then dereferenced.

When applied to an array, the subscript expression is an.

When applied to a pointer, the subscript expression is always an lvalue.

The type is not allowed to be an, even if the size or internal structure of  is never used, as in.

In, for every object type (possibly cv-qualified), the following function signature participates in overload resolution:

Built-in indirection operator
The indirection operator expressions have the form

The operand of the built-in indirection operator must be pointer to object or a pointer to function, and the result is the lvalue referring to the object or function to which points.

A pointer to (possibly -qualified) cannot be dereferenced. Pointers to other incomplete types can be dereferenced, but the resulting lvalue can only be used in contexts that allow an lvalue of incomplete type, e.g. when initializing a reference.

In, for every type that is either object type (possibly cv-qualified) or function type (not const- or ref-qualified), the following function signature participates in overload resolution:

Built-in address-of operator
The address-of operator expressions have the form

@1@ If the operand is an lvalue expression of some object or function type, creates and returns a prvalue of type , with the same cv qualification, that is pointing to the object or function designated by the operand. If the operand has incomplete type, the pointer can be formed, but if that incomplete type happens to be a class that defines its own, it is unspecified whether the built-in or the overload is used. For the operands of type with user-defined, std may be used to obtain the true pointer. Note that, unlike C99 and later C versions, there's no special case for the unary applied to the result of the unary. @@ If the operand is the name of an overloaded function, the address may be taken only if the overload can be resolved due to context. See for details.

@2@ If the operand is a qualified name of a non-static or member, e.g., the result is a prvalue  or  of type  in class. Note that neither nor  nor even  may be used to initialize a pointer to member.

In, this operator does not introduce any additional function signatures: built-in address-of operator does not apply if there exists an overloaded that is a.

Built-in member access operators
The member access operator expressions have the form

@1@ The must be an expression of  class type. @2@ The must be an expression of pointer to complete class type. @3,4@ The must be an expression of scalar type (see below).

is evaluated even if it is not necessary (e.g. when the second operand names a static member).

is a name of (formally, an that names) a data member or member function of  or of an unambiguous and accessible base class  of  (e.g.  or ), optionally  (e.g.  or ), optionally using  (e.g.  or ).

If a user-defined is called,  is called again on the resulting value, recursively, until an  is reached that returns a plain pointer. After that, built-in semantics are applied to that pointer.

The expression is exactly equivalent to  for built-in types; that is why the following rules address only.

In the expression : @1@ if is a : Essentially, is evaluated and discarded in both cases; @2@ if is a : If is not a  member, the  of the result is the union of the cv-qualifications of  and, otherwise (if  is a mutable member), it is the union of the volatile-qualifications of  and ; @3@ if is a, the result is an lvalue designating that static member function. Essentially, is evaluated and discarded in this case; @4@ if is a  including a, the result is a special kind of prvalue designating that non-static member function of  that can only be used as the left-hand operand of a member function call operator, and for no other purpose; @5@ if is a member enumerator, given the type of  as, the result is  of type  whose value is the value of the enumerator; @6@ if is a, the program is ill-formed; @7@ if has a  and  is a  followed by the  or  designating the same type (minus cv-qualifications), optionally, the result is a special kind of prvalue that can only be used as the left-hand operand of a function call operator, and for no other purpose. The resulting function call expression is called pseudo destructor call. It takes no arguments, returns void, evaluates, and ends the lifetime of its result object. This is the only case where the left-hand operand of has non-class type. Allowing pseudo destructor call makes it possible to write code without having to know if a destructor exists for a given type.
 * if is of reference type , the result is an lvalue of type  designating the object or function to which the reference is bound,
 * otherwise, given the type of as, the result is an lvalue of type  designating that static data member.
 * if is of reference type , the result is an lvalue of type  designating the object or function to which the corresponding reference member of  is bound,
 * otherwise, if is an lvalue, the result is an lvalue designating that non-static data member of ,
 * otherwise (if is an ), the result is an  designating that non-static data member of.

cannot be overloaded, and for, in , the built-in operator does not introduce any additional function signatures: built-in does not apply if there exists an overloaded  that is a.

Built-in pointer-to-member access operators
The member access operator expressions through pointers to members have the form

@1@ must be an expression of class type. @2@ must be an expression of type pointer to class type.

The second operand of both operators is an expression of type pointer to member ( or ) of  or pointer to member of an unambiguous and accessible base class  of.

The expression is exactly equivalent to  for built-in types; that is why the following rules address only.

In the expression : @1@ if is a pointer to data member, @2@ if is a pointer to member function, the result is a special kind of prvalue designating that member function that can only be used as the left-hand operand of a member function call operator, and for no other purpose; @3@ cv-qualification rules are the same as for member of object operator, with one additional rule: a pointer to member that refers to a mutable member cannot be used to modify that member in a const object; @4@ if is a null pointer-to-member value, the behavior is undefined; @5@ if the of  does not contain the member to which  refers, the behavior is undefined; @6@ if is an rvalue and  points to a member function with ref-qualifier, the program is ill-formed ;
 * if is an lvalue, the result is an lvalue designating that data member,
 * otherwise (if is an ), the result is an  designating that data member;

In, for every combination of types , , , where class type is either the same class as  or an unambiguous and accessible base class of , and  is either an object or function type, the following function signature participates in overload resolution:

where both operands may be cv-qualified, in which case the return type's cv-qualification is the union of the cv-qualification of the operands.

Standard library
Subscript operator is overloaded by many standard container classes:

The indirection and member operators are overloaded by many iterators and smart pointer classes:

No standard library classes overload. The best known example of overloaded is the Microsoft COM class, although it can also appear in EDSLs such as boost.spirit

No standard library classes overload. It was suggested that it could be part of smart pointer interface, and in fact is used in that capacity by actors in boost.phoenix, but is more common in EDSLs such as cpp.react.