Member access operators
Accesses a member of an object.
Operator name | Syntax | Overloadable | Prototype examples (for class T) | |
---|---|---|---|---|
Inside class definition | Outside class definition | |||
array subscript | a[b] | Yes | R& T::operator[](const T2& b); | N/A |
indirection (variable pointed to by a) | *a | Yes | R& T::operator*(); | R& operator*(T &a); |
address of | &a | Yes | R* T::operator&(); | R* operator&(T &a); |
member of object | a.b | No | N/A | N/A |
member of pointer | a->b | Yes | R* T::operator->() | N/A |
pointer to member of object | a.*b | No | N/A | N/A |
pointer to member of pointer | a->*b | Yes | R* T::operator->*(R) | R* T::operator->*(T, R) |
|
Contents |
[edit] Explanation
array subscript operator provides access to the elements in the internal array
indirection, member of pointer and pointer to member of pointer operators provide provide pointer semantics for any object.
member of pointer and pointer to member of pointer operators return a pointer to the actual object which will be used for member access.
[edit] Built-in subscript operator
For every object type T (possibly cv-qualified), the following function signature participates in overload resolution:
T& operator[](T*, std::ptrdiff_t); |
||
T& operator[](std::ptrdiff_t, T*); |
||
The non-pointer operand may be any expression of integral or unscoped enumeration type, it is implicitly converted to std::ptrdiff_t. The expression A[B] is exactly identical to the expression *(A+B), that is, 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 at another element of the same array, following the rules of pointer arithmetics, and is then dereferenced.
#include <iostream> int main() { int a[4] = {1,2,3,4}; int* p = &a[2]; std::cout << p[1] << p[-1] << 1[p] << (-1)[p] << '\n'; }
Output:
4242
[edit] Built-in indirection operator
For every type T that is either object type (possibly cv-qualified) or function type (not const- or ref-qualified), the following function signature participates in overload resolution:
T& operator*(T*); |
||
The operand of the built-in indirection operator is a pointer to object or function, and the result is the lvalue that the pointer is pointing at. Note that a pointer to incomplete type can be dereferenced, e.g. when initializing a reference.
#include <iostream> int f() { return 42; } int main() { int n = 1; int* pn = &n; int& r = *pn; // lvalue can be bound to a reference int m = *pn; // indirection + lvalue-to-rvalue conversion int (*fp)() = &f; int (&fr)() = *fp; // function lvalue can be bound to a reference }
[edit] Built-in address-of operator
The operand of the built-in operator& is either an lvalue expression of any type or the qualified name of a non-static member function/object in some class. This operator does not participate in overload resolution, special rules are used:
If the operand is an lvalue expression of some type T, operator& creates and returns a prvalue of type T*, with the same cv qualification, that is pointing at the object 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 operator&, the behavior is undefined. For the operands of type with user-defined operator&, std::addressof may be used to obtain the true pointer.
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, that is, the result of operator& is used to initialize an object, in a cast expression, on the left of an assignment, as a function parameter or in a return statement.
If the operand is a qualified name of a non-static member, e.g. &Class::member, the result is a prvalue pointer to member function or pointer to member object of type T in class C. Note that neither &member nor Class::member nor even (&Class::member) may be used to initialize a pointer to member.
void f(int) {} void f(double) {} struct A { int i; }; struct B { void f(); }; int main() { int n = 1; int* pn = &n; // pointer int A::* mp = &A::i; // pointer to member object void (B::*mpf)() = &B::f; // pointer to member function // auto pf2 = &f; // error: ambiguous overloaded function type void (*pf)(int) = &f; // overload resolution due to initialization auto pf2 = static_cast<void(*)(int)>(&f); // overload resolution due to cast }
[edit] Built-in member access operators
The left operand of the built-in operator. and operator-> is an expression of complete class type T (for operator.) or pointer to complete class type T* (for operator->, which is evaluated before the operator can be called. The right operand is the name of a member object or member function of T or of one of T's base classes, e.g. expr.member, optionally qualified, e.g. expr.name::member, optionally prepended by the keyword template, e.g. expr.template member.
The expression A->B is exactly equivalent to (*A).B for builtin types. If a user-defined operator-> is provided, operator-> is called again on the value that it returns, recursively, until the operator-> is reached that returns a plain pointer. After that, builtin semantics are applied to that pointer.
In the expression expr.B,
#include <iostream> template<typename T> struct P { typedef T* ptr; }; template<typename T> struct A { class B {}; enum E {RED = 1, BLUE = 2}; int n; static int sn; int f() { return 10+n; } static int fs() { return 4; } A(int n) : n(n) {} // keyword template needed to refer to a dependent template member void g() { T obj; int* p = obj.template ptr<int>; p->~T(); // T is int, this calls int's pseudo destructor } }; template<> int A<P<int>>::sn = 2; int main() { A<P<int>> a(1); std::cout << a.n << ' ' << a.sn << ' ' // << A::sn also works << a.f() << ' ' << a.fs() << ' ' // A::fs() also works << a.RED << ' ' // nested type not allowed // << a.B // nested type not allowed ; }
Output:
1 2 11 4 1
[edit] Built-in pointer-to-member access operators
The right operand of both operator*. and operator->* is an expression of type pointer to member in class T. For operator*., the left operand is an expression of class type T, or of some derived class in which T is unambiguous accessible base. For operator->*, the left operand is a pointer to T or to its base.
For every combination of types B, D, T, where D is either the same as B or a class derived from B, and T is either object or function type, the following function signature participates in overload resolution:
T& operator->*(B*, T D::*); |
||
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.
The expression E1->*E2 is exactly equivalent to (*E1).*E2 for built-in types.
For the expression expr.*ptr,
#include <iostream> struct S { mutable int mi; int f(int n) { return mi+n; } S(int n) : mi(n) {} }; struct D : public S { D(int n) : S(n) {} }; int main() { int S::* pmi = &S::mi; int (S::*mpf)(int) = &S::f; const S s(7); // s.*pmi = 10; // cannot modify through mutable std::cout << s.*pmi << '\n'; D d(7); // base pointers work with derived object D* dp = &d; std::cout << (d.*mpf)(7) << ' ' << (dp->*mpf)(8) << '\n'; }
Output:
7 14 15
[edit] Standard library
Subscript operator is overloaded by many standard container classes
accesses specific bit (public member function of std::bitset) | |
provides indexed access to the managed array (public member function of std::unique_ptr) | |
access specified character (public member function of std::basic_string) | |
access specified element (public member function of std::array) | |
access specified element (public member function of std::deque) | |
access specified element (public member function of std::vector) | |
access specified element (public member function of std::map) | |
access specified element (public member function of std::unordered_map) | |
accesses an element by index (public member function of std::reverse_iterator) | |
obtains rvalue reference to indexed element (public member function of std::move_iterator) | |
get/set valarray element, slice, or mask (public member function of std::valarray) | |
returns specified sub-match (public member function of std::match_results) |
The indirection and member access operators are overloaded by many iterators and smart pointer classes
dereferences pointer to the managed object (public member function of std::unique_ptr) | |
dereferences pointer to the managed object (public member function of std::shared_ptr) | |
accesses the managed object (public member function of std::auto_ptr) | |
returns a reference to this raw_storage_iterator (public member function of std::raw_storage_iterator) | |
dereferences the decremented underlying iterator (public member function of std::reverse_iterator) | |
no-op (public member function of std::back_insert_iterator) | |
no-op (public member function of std::front_insert_iterator) | |
no-op (public member function of std::insert_iterator) | |
accesses the pointed-to element (public member function of std::move_iterator) | |
obtains a copy of the current element accesses a member of the current element (public member function of std::istream_iterator) | |
no-op (public member function of std::ostream_iterator) | |
(since C++11) |
obtains a copy of the current character accesses a member of the current character, if CharT has members (public member function of std::istreambuf_iterator) |
no-op (public member function of std::ostreambuf_iterator) | |
accesses the current match accesses a member of the current match (public member function of std::regex_iterator) | |
accesses the current result accesses a member of the current result (public member function of std::regex_token_iterator) |
No standard library classes overload operator& or operator->*. The best known example of overloaded operator& is the Microsoft COM class CComPtr. operator->* is sometimes overloaded by third-party custom smart pointers.
[edit] See also
Common operators | ||||||
---|---|---|---|---|---|---|
assignment | increment decrement |
arithmetic | logical | comparison | member access |
other |
a = b |
++a |
+a |
!a |
a == b |
a[b] |
a(...) |
Special operators | ||||||
static_cast converts one type to another compatible type |