Namensräume
Varianten
Aktionen

Member-Zugriffsoperatoren

Von cppreference.com
< cpp‎ | Sprache
 
 
C++ Sprache
Allgemeine Themen
Kontrollfluss
Bedingte Ausführungsaussagen
if
Iterationsanweisungen (Schleifen)
for
Bereichs-for (C++11)
Sprunganweisungen
Funktionen
Funktionsdeklaration
Lambda-Funktionsausdruck
inline-Spezifizierer
Dynamische Ausnahmespezifikationen (bis C++17*)
noexcept-Spezifizierer (C++11)
Ausnahmen
Namensräume
Typen
Spezifizierer
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Speicherdauer-Spezifizierer
Initialisierung
Ausdrücke
Alternative Darstellungen
Literale
Boolesch - Ganzzahl - Gleitkommazahl
Zeichen - String - nullptr (C++11)
Benutzerdefinierte (C++11)
Dienstprogramme
Attribute (C++11)
Typen
typedef-Deklaration
Typalias-Deklaration (C++11)
Umwandlungen
Speicherzuweisung
Klassen
Klassenspezifische Funktionseigenschaften
explicit (C++11)
static

Spezielle Member-Funktionen
Templates
Sonstiges
 
 

Greift auf ein Element seines Operanden zu.

  Operator Name             Syntax           Überladbar Prototypenbeispiele (für class T)
Innerhalb der Klassendefinition Außerhalb der Klassendefinition
Indexzugriff a[b] Ja R& T::operator[](S b); N/A
a[...] (seit C++23) R& T::operator[](...);
Indirektion *a Ja R& T::operator*(); R& operator*(T a);
Adressoperator &a Ja R* T::operator&(); R* operator&(T a);
Element eines Objekts a.b Nein N/A N/A
Element eines Zeigers a->b Ja R* T::operator->(); N/A
Zeiger auf Element eines Objekts a.*b Nein N/A N/A
Zeiger auf Element eines Zeigers a->*b Ja R& T::operator->*(S b); R& operator->*(T a, S b);
Anmerkungen
  • Wie bei den meisten benutzerdefinierten Überladungen sollten die Rückgabetypen den von den integrierten Operatoren bereitgestellten Rückgabetypen entsprechen, damit die benutzerdefinierten Operatoren genauso verwendet werden können wie die integrierten. In einer benutzerdefinierten Operatorüberladung kann jedoch jeder Typ als Rückgabetyp verwendet werden (einschließlich void). Eine Ausnahme bildet operator->, der einen Zeiger oder eine andere Klasse mit überladenem operator-> zurückgeben muss, um realistisch verwendbar zu sein.

Inhalt

[bearbeiten] Erklärung

Der integrierte Indexoperator ermöglicht den Zugriff auf ein Objekt, auf das der Zeiger- oder Array-Operand zeigt.

Der integrierte Indirektionsoperator ermöglicht den Zugriff auf ein Objekt oder eine Funktion, auf die der Zeigeroperand zeigt.

Der integrierte Adressoperator erstellt einen Zeiger, der auf das Objekt oder die Funktion des Operanden zeigt.

Die Operatoren "Element eines Objekts" und "Zeiger auf Element eines Objekts" ermöglichen den Zugriff auf ein Datenelement oder eine Memberfunktion des Objektoperanden.

Die integrierten Operatoren "Element eines Zeigers" und "Zeiger auf Element eines Zeigers" ermöglichen den Zugriff auf ein Datenelement oder eine Memberfunktion der Klasse, auf die der Zeigeroperand zeigt.

[bearbeiten] Integrierter Indexoperator

Indexoperator-Ausdrücke haben die Form

expr1 [expr2 ] (1)
expr1 [{expr , ...}] (2) (seit C++11)
expr1 [expr2 , expr , ...] (3) (seit C++23)
1) Für den integrierten Operator muss einer der Ausdrücke (entweder expr1 oder expr2) ein Glvalue vom Typ "Array von T" oder ein Prvalue vom Typ "Zeiger auf T" sein, während der andere Ausdruck (expr2 bzw. expr1) ein Prvalue einer unaufgelösten Enumeration oder eines ganzzahligen Typs sein muss. Das Ergebnis dieses Ausdrucks hat den Typ T. expr2 darf kein unparenthetischer Komma-Ausdruck sein.(seit C++23)
2) Die Form mit einer in geschweifte Klammern eingeschlossenen Liste innerhalb der eckigen Klammern wird nur zum Aufrufen eines überladenen operator[] verwendet.
3) Die Form mit einer kommagetrennten Ausdrucksliste innerhalb der eckigen Klammern wird nur zum Aufrufen eines überladenen operator[] verwendet.

Der integrierte Indexausdruck E1[E2] ist exakt identisch mit dem Ausdruck *(E1 + E2), abgesehen von seiner Wertkategorie (siehe unten) und Auswertungsreihenfolge(seit C++17): Der Zeigeroperand (der das Ergebnis einer Array-zu-Zeiger-Konvertierung sein kann und auf ein Element eines Arrays oder ein Element danach zeigen muss) wird so angepasst, dass er auf ein anderes Element desselben Arrays zeigt, gemäß den Regeln der Zeigerarithmetik, und wird dann dereferenziert.

Wenn auf ein Array angewendet, ist der Indexausdruck ein lvalue, wenn das Array ein lvalue ist, und ein xvalue, wenn nicht(seit C++11).

Wenn auf einen Zeiger angewendet, ist der Indexausdruck immer ein lvalue.

Der Typ T darf kein unvollständiger Typ sein, auch wenn die Größe oder interne Struktur von T nie verwendet wird, wie in &x[0].

Die Verwendung eines unparenthetischen Komma-Ausdrucks als zweites (rechtes) Argument eines Indexoperators ist veraltet.

Zum Beispiel ist a[b, c] veraltet und a[(b, c)] nicht.

(seit C++20)
(bis C++23)

Ein unparenthetischer Komma-Ausdruck darf nicht das zweite (rechte) Argument eines Indexoperators sein. Zum Beispiel ist a[b, c] entweder fehlerhaft oder äquivalent zu a.operator[](b, c).

Klammern sind erforderlich, um einen Komma-Ausdruck als Index zu verwenden, z. B. a[(b, c)].

(seit C++23)

Bei der Überladungsauflösung für benutzerdefinierte Operatoren nimmt für jedes Objekttyp T (möglicherweise cv-qualifiziert) die folgende Funktionssignatur an der Überladungsauflösung teil:

T& operator[](T*, std::ptrdiff_t);
T& operator[](std::ptrdiff_t, T*);
#include <iostream>
#include <map>
#include <string>
 
int main()
{
    int a[4] = {1, 2, 3, 4};
    int* p = &a[2];
    std::cout << p[1] << p[-1] << 1[p] << (-1)[p] << '\n';
 
    std::map<std::pair<int, int>, std::string> m;
    m[{1, 2}] = "abc"; // uses the [{...}] version
}

Ausgabe

4242

[bearbeiten] Integrierter Indirektionsoperator

Indirektionsoperator-Ausdrücke haben die Form

*expr

Der Operand des integrierten Indirektionsoperators muss ein Zeiger auf ein Objekt oder eine Zeiger auf eine Funktion sein, und das Ergebnis ist das lvalue, das sich auf das Objekt oder die Funktion bezieht, auf die expr zeigt. Wenn expr nicht tatsächlich auf ein Objekt oder eine Funktion zeigt, ist das Verhalten undefiniert (mit Ausnahme des von typeid spezifizierten Falls).

Ein Zeiger auf void (möglicherweise cv-qualifiziert) kann nicht dereferenziert werden. Zeiger auf andere unvollständige Typen können dereferenziert werden, aber das resultierende lvalue darf nur in Kontexten verwendet werden, die ein lvalue eines unvollständigen Typs zulassen, z. B. bei der Initialisierung einer Referenz.

Bei der Überladungsauflösung für benutzerdefinierte Operatoren nimmt für jeden Typ T, der entweder ein Objekttyp (möglicherweise cv-qualifiziert) oder ein Funktionstyp (nicht const- oder ref-qualifiziert) ist, die folgende Funktionssignatur an der Überladungsauflösung teil:

T& operator*(T*);
#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
 
    [](...){}(r, m, fr); // removes possible "unused variable" warnings
}

[bearbeiten] Integrierter Adressoperator

Adressoperator-Ausdrücke haben die Form

&expr (1)
&Klasse ::Mitglied (2)
1) Wenn der Operand ein lvalue-Ausdruck eines Objekt- oder Funktionstyps T ist, erstellt und gibt operator& einen prvalue vom Typ T* mit derselben cv-Qualifikation zurück, der auf das Objekt oder die Funktion zeigt, auf die der Operand verweist. Wenn der Operand einen unvollständigen Typ hat, kann der Zeiger gebildet werden, aber wenn dieser unvollständige Typ eine Klasse ist, die ihren eigenen operator& definiert, ist es nicht spezifiziert, ob der integrierte oder der überladene Operator verwendet wird. Für Operanden vom Typ mit benutzerdefiniertem operator& kann std::addressof verwendet werden, um den tatsächlichen Zeiger zu erhalten. Beachten Sie, dass im Gegensatz zu C99 und späteren C-Versionen keine Sonderbehandlung für den unären operator& angewendet wird, der auf das Ergebnis des unären operator* angewendet wird.
Wenn expr den Namen einer überladenen Funktion bezeichnet, kann die Adresse nur genommen werden, wenn die Überladung aufgrund des Kontexts aufgelöst werden kann. Einzelheiten finden Sie unter Adresse einer überladenen Funktion.

Wenn expr eine explizite Objekt-Memberfunktion benennt, muss expr ein qualifizierter Bezeichner sein. Das Anwenden von & auf einen nicht qualifizierten Bezeichner, der eine explizite Objekt-Memberfunktion benennt, ist fehlerhaft.

(seit C++23)
2) Wenn der Operand ein qualifizierter Name eines nicht-statischen oder variantenartigen Members ist außer einer expliziten Objekt-Memberfunktion(seit C++23), z. B. &C::member, ist das Ergebnis ein prvalue Zeiger auf eine Memberfunktion oder ein Zeiger auf ein Datenmember vom Typ T in Klasse C. Beachten Sie, dass weder &member noch C::member oder sogar &(C::member) zur Initialisierung eines Zeigers auf ein Mitglied verwendet werden können.

Bei der Überladungsauflösung für benutzerdefinierte Operatoren führt dieser Operator keine zusätzlichen Funktionssignaturen ein: Der integrierte Adressoperator wird nicht angewendet, wenn ein überladener operator& existiert, der eine funktionierende Funktion ist.

void f(int) {}
void f(double) {}
 
struct A { int i; };
struct B { void f(); };
 
int main()
{
    int n = 1;
    int* pn = &n;    // pointer
    int* pn2 = &*pn; // pn2 == pn
 
    int A::* mp = &A::i;      // pointer to data member
    void (B::*mpf)() = &B::f; // pointer to member function
 
    void (*pf)(int) = &f; // overload resolution due to initialization context
//  auto pf2 = &f; // error: ambiguous overloaded function type
    auto pf2 = static_cast<void (*)(int)>(&f); // overload resolution due to cast
}

[bearbeiten] Integrierte Member-Zugriffsoperatoren

Member-Zugriffsoperator-Ausdrücke haben die Form

expr .template(optional) id-expr (1)
expr ->template(optional) id-expr (2)
expr .pseudo-destructor (3)
expr ->pseudo-destructor (4)
1) expr muss ein Ausdruck eines vollständigen Klassentyps T sein.
Wenn id-expr ein statisches Element oder einen Enumerator benennt, ist expr ein Ausdruck mit verworfenem Wert.
2) expr muss ein Ausdruck eines Zeigers auf einen vollständigen Klassentyp T* sein.
3,4) expr muss ein Ausdruck eines Skalarertyps sein (siehe unten).

id-expr ist ein Name für (formal, ein Bezeichnerausdruck, der benennt) ein Datenmember oder eine Memberfunktion von T oder einer eindeutigen und zugänglichen Basisklasse B von T (z. B. E1.E2 oder E1->E2), optional qualifiziert (z. B. E1.B::E2 oder E1->B::E2), optional unter Verwendung des template-Disambiguators (z. B. E1.template E2 oder E1->template E2).

Wenn ein benutzerdefinierter operator-> aufgerufen wird, wird operator-> rekursiv auf dem resultierenden Wert erneut aufgerufen, bis ein operator-> erreicht wird, der einen einfachen Zeiger zurückgibt. Danach werden die integrierten Semantiken auf diesen Zeiger angewendet.

Der Ausdruck E1->E2 ist für integrierte Typen exakt äquivalent zu (*E1).E2; daher befassen sich die folgenden Regeln nur mit E1.E2.

Im Ausdruck E1.E2

1) Wenn E2 ein statisches Datenelement ist
  • Wenn E2 vom Referenztyp T& ist oder T&&(seit C++11), ist das Ergebnis ein lvalue vom Typ T, das das Objekt oder die Funktion bezeichnet, an die die Referenz gebunden ist.
  • Andernfalls, wenn der Typ von E2 T ist, ist das Ergebnis ein lvalue vom Typ T, das dieses statische Datenelement bezeichnet.
Im Wesentlichen wird E1 in beiden Fällen ausgewertet und verworfen.
2) Wenn E2 ein nicht-statisches Datenelement ist
  • Wenn E2 vom Referenztyp T& ist oder T&&(seit C++11), ist das Ergebnis ein lvalue vom Typ T, das das Objekt oder die Funktion bezeichnet, an die die entsprechende Referenz von E1 gebunden ist.
  • Andernfalls, wenn E1 ein lvalue ist, ist das Ergebnis ein lvalue, das dieses nicht-statische Datenelement von E1 bezeichnet.
  • Andernfalls (wenn E1 ein rvalue(bis C++17)xvalue ist (was von prvalue materialisiert werden kann)(seit C++17)), ist das Ergebnis ein rvalue(bis C++11)xvalue(seit C++11), das dieses nicht-statische Datenelement von E1 bezeichnet.
Wenn E2 kein mutable Member ist, ist die cv-Qualifikation des Ergebnisses die Vereinigung der cv-Qualifikationen von E1 und E2; andernfalls (wenn E2 ein mutable Member ist) ist es die Vereinigung der volatile-Qualifikationen von E1 und E2.
3) Wenn E2 eine Überladungsmeng (von einer oder mehreren statischen Memberfunktionen und nicht-statischen Memberfunktionen) ist, muss E1.E2 der (möglicherweise geklammerte) linke Operand eines Memberfunktionsaufrufoperators sein, und die Funktionsüberladungsauflösung wird verwendet, um die Funktion auszuwählen, auf die sich E2 bezieht, danach
  • Wenn E2 eine statische Memberfunktion ist, ist das Ergebnis ein lvalue, das diese statische Memberfunktion bezeichnet. Im Wesentlichen wird E1 in diesem Fall ausgewertet und verworfen.
  • Andernfalls (wenn E2 eine nicht-statische Memberfunktion ist), ist das Ergebnis ein prvalue, das diese nicht-statische Memberfunktion von E1 bezeichnet.
4) Wenn E2 ein Member-Enumerator ist, ist das Ergebnis vom Typ T ein rvalue(bis C++11)prvalue(seit C++11) dessen Wert der Wert des Enumerators ist.
5) Wenn E2 ein verschachtelter Typ ist, ist das Programm fehlerhaft.
6) Wenn E1 einen Skalarwert-Typ hat und E2 ein ~ gefolgt vom Typnamen oder decltype-Spezifizierer ist, der denselben Typ bezeichnet (abzüglich cv-Qualifikationen), optional qualifiziert, ist das Ergebnis eine spezielle Art von prvalue, die nur als linker Operand eines Funktionsaufrufoperators verwendet werden kann und für keinen anderen Zweck.
Der resultierende Funktionsaufrufausdruck wird als Pseudo-Destruktoraufruf bezeichnet. Er nimmt keine Argumente, gibt void zurück, wertet E1 aus und beendet die Lebensdauer seines Ergebnisobjekts. Dies ist der einzige Fall, in dem der linke Operand von operator. einen Nicht-Klassentyp hat. Das Zulassen von Pseudo-Destruktoraufrufen ermöglicht das Schreiben von Code, ohne wissen zu müssen, ob für einen bestimmten Typ ein Destruktor existiert.

operator. kann nicht überladen werden, und für operator-> führt bei der Überladungsauflösung für benutzerdefinierte Operatoren der integrierte Operator keine zusätzlichen Funktionssignaturen ein: Der integrierte operator-> wird nicht angewendet, wenn ein überladener operator-> existiert, der eine funktionierende Funktion ist.

#include <cassert>
#include <iostream>
#include <memory>
 
struct P
{
    template<typename T>
    static T* ptr() { return new T; }
};
 
template<typename T>
struct A
{
    A(int n): n(n) {}
 
    int n;
    static int sn;
 
    int f() { return 10 + n; }
    static int sf() { return 4; }
 
    class B {};
    enum E {RED = 1, BLUE = 2};
 
    void g()
    {
        typedef int U;
 
        // keyword template needed for a dependent template member
        int* p = T().template ptr<U>();
        p->~U(); // U is int, calls int's pseudo destructor
        delete p;
    }
};
 
template<>
int A<P>::sn = 2;
 
struct UPtrWrapper
{
    std::unique_ptr<std::string> uPtr;
    std::unique_ptr<std::string>& operator->() { return uPtr; }
};
 
int main()
{
    A<P> a(1);
    std::cout << a.n << ' '
              << a.sn << ' '   // A::sn also works
              << a.f() << ' ' 
              << a.sf() << ' ' // A::sf() also works
//            << &a.f << ' '   // error: ill-formed if a.f is not the
                               // left-hand operand of operator()
//            << a.B << ' '    // error: nested type not allowed
              << a.RED << ' '; // enumerator
 
    UPtrWrapper uPtrWrap{std::make_unique<std::string>("wrapped")};
    assert(uPtrWrap->data() == uPtrWrap.operator->().operator->()->data());
}

Ausgabe

1 2 11 4 1

Wenn E2 ein nicht-statisches Element ist und das Ergebnis von E1 ein Objekt ist, dessen Typ nicht ähnlich zum Typ von E1 ist, ist das Verhalten undefiniert.

struct A { int i; };
struct B { int j; };
struct D : A, B {};
 
void f()
{
    D d;
    static_cast<B&>(d).j;      // OK, object expression designates the B subobject of d
    reinterpret_cast<B&>(d).j; // undefined behavior
}

[bearbeiten] Integrierte Zeiger-auf-Member-Zugriffsoperatoren

Member-Zugriffsoperator-Ausdrücke über Zeiger auf Member haben die Form

lhs .*rhs (1)
lhs ->*rhs (2)
1) lhs muss ein Ausdruck eines Klassentyps T sein.
2) lhs muss ein Ausdruck eines Zeigers auf einen Klassentyp T* sein.

rhs muss ein rvalue vom Typ Zeiger auf Member (Daten oder Funktion) von T oder Zeiger auf Member einer eindeutigen und zugänglichen Basisklasse B von T sein.

Der Ausdruck E1->*E2 ist für integrierte Typen exakt äquivalent zu (*E1).*E2; daher befassen sich die folgenden Regeln nur mit E1.*E2.

Im Ausdruck E1.*E2

1) wenn E2 ein Zeiger auf ein Datenelement ist,
  • wenn E1 ein lvalue ist, ist das Ergebnis ein lvalue, das dieses Datenelement bezeichnet,
  • andernfalls (wenn E1 ein rvalue(bis C++17)xvalue ist (was von prvalue materialisiert werden kann)(seit C++17)), ist das Ergebnis ein rvalue(bis C++11)xvalue(seit C++11), das dieses Datenelement bezeichnet;
2) wenn E2 ein Zeiger auf eine Memberfunktion ist, ist das Ergebnis ein spezieller prvalue, der diese Memberfunktion bezeichnet und nur als linker Operand eines Memberfunktionsaufrufoperators verwendet werden kann und für keinen anderen Zweck;
3) Die cv-Qualifikationsregeln sind dieselben wie für den Operator "Element eines Objekts", mit einer zusätzlichen Regel: Ein Zeiger auf ein Member, der sich auf ein mutable Member bezieht, kann nicht verwendet werden, um dieses Member in einem const-Objekt zu ändern;
4) Wenn E2 ein Null-Zeiger-auf-Member-Wert ist, ist das Verhalten undefiniert;
5) Wenn das Ergebnis E1 ein Objekt ist, dessen Typ nicht ähnlich zum Typ von E1 ist, oder sein am höchsten abgeleitetes Objekt nicht das Member enthält, auf das sich E2 bezieht, ist das Verhalten undefiniert;
6) Wenn E1 ein rvalue ist und E2 auf eine Memberfunktion mit einem Ref-Qualifier & zeigt, ist das Programm fehlerhaft es sei denn, die Memberfunktion hat die cv-Qualifikation const, aber nicht volatile(seit C++20);
7) Wenn E1 ein lvalue ist und E2 auf eine Memberfunktion mit einem Ref-Qualifier && zeigt, ist das Programm fehlerhaft.
(seit C++11)

Bei der Überladungsauflösung für benutzerdefinierte Operatoren wird für jede Kombination von Typen D, B, R, wobei der Klassentyp B entweder die gleiche Klasse wie D oder eine eindeutige und zugängliche Basisklasse von D ist und R entweder ein Objekt- oder ein Funktionstyp ist, die folgende Funktionssignatur zur Überladungsauflösung herangezogen:

R& operator->*(D*, R B::*);

wobei beide Operanden cv-qualifiziert sein können. In diesem Fall ist die cv-Qualifikation des Rückgabetyps die Vereinigung der cv-Qualifikationen der Operanden.

#include <iostream>
 
struct S
{
    S(int n) : mi(n) {}
    mutable int mi;
    int f(int n) { return mi + n; }
};
 
struct D : public S
{
    D(int n) : S(n) {}
};
 
int main()
{
    int S::* pmi = &S::mi;
    int (S::* pf)(int) = &S::f;
 
    const S s(7);
//  s.*pmi = 10; // error: cannot modify through mutable
    std::cout << s.*pmi << '\n';
 
    D d(7); // base pointers work with derived object
    D* pd = &d;
    std::cout << (d.*pf)(7) << ' '
              << (pd->*pf)(8) << '\n';
}

Ausgabe

7
14 15

[bearbeiten] Standardbibliothek

Der Indexoperator wird von vielen Standard-Containerklassen überladen.

greift auf ein bestimmtes Bit zu
(öffentliche Memberfunktion von std::bitset<N>) [bearbeiten]
ermöglicht den indizierten Zugriff auf das verwaltete Array
(öffentliche Memberfunktion von std::unique_ptr<T,Deleter>) [bearbeiten]
greift auf das angegebene Zeichen zu
(öffentliche Memberfunktion von std::basic_string<CharT,Traits,Allocator>) [bearbeiten]
Greift auf ein bestimmtes Element zu
(öffentliche Memberfunktion von std::array<T,N>) [bearbeiten]
Greift auf ein bestimmtes Element zu
(öffentliche Memberfunktion von std::deque<T,Allocator>) [bearbeiten]
Greift auf ein bestimmtes Element zu
(öffentliche Memberfunktion von std::vector<T,Allocator>) [bearbeiten]
greift auf ein Element zu oder fügt es ein
(öffentliche Memberfunktion von std::map<Key,T,Compare,Allocator>) [bearbeiten]
greift auf ein Element zu oder fügt es ein
(öffentliche Memberfunktion von std::unordered_map<Key,T,Hash,KeyEqual,Allocator>) [bearbeiten]
greift per Index auf ein Element zu
(öffentliche Memberfunktion von std::reverse_iterator<Iter>) [bearbeiten]
greift per Index auf ein Element zu
(öffentliche Memberfunktion von std::move_iterator<Iter>) [bearbeiten]
liest/schreibt Array-Element, Slice oder Maske
(öffentliche Memberfunktion von std::valarray<T>) [bearbeiten]
gibt die angegebene Teilübereinstimmung zurück
(öffentliche Memberfunktion von std::match_results<BidirIt,Alloc>) [bearbeiten]

Die Dereferenzierungs- und Memberoperatoren werden von vielen Iteratoren und Smart-Pointer-Klassen überladen.

Dereferenziert den Zeiger auf das verwaltete Objekt
(öffentliche Memberfunktion von std::unique_ptr<T,Deleter>) [bearbeiten]
dereferenziert den gespeicherten Zeiger
(öffentliche Memberfunktion von std::shared_ptr<T>) [bearbeiten]
greift auf das verwaltete Objekt zu
(öffentliche Memberfunktion von std::auto_ptr<T>) [bearbeiten]
dereferenziert den Iterator
(öffentliche Memberfunktion von std::raw_storage_iterator<OutputIt,T>) [bearbeiten]
dereferenziert den dekrementierten zugrundeliegenden Iterator
(öffentliche Memberfunktion von std::reverse_iterator<Iter>) [bearbeiten]
no-op
(öffentliche Memberfunktion von std::back_insert_iterator<Container>) [bearbeiten]
no-op
(öffentliche Memberfunktion von std::front_insert_iterator<Container>) [bearbeiten]
no-op
(öffentliche Memberfunktion von std::insert_iterator<Container>) [bearbeiten]
greift auf das dereferenzierte Element zu
(öffentliche Memberfunktion von std::move_iterator<Iter>) [bearbeiten]
gibt das aktuelle Element zurück
(öffentliche Memberfunktion von std::istream_iterator<T,CharT,Traits,Distance>) [bearbeiten]
no-op
(öffentliche Memberfunktion von std::ostream_iterator<T,CharT,Traits>) [bearbeiten]
erhält eine Kopie des aktuellen Zeichens
(öffentliche Memberfunktion von std::istreambuf_iterator<CharT,Traits>) [bearbeiten]
no-op
(öffentliche Memberfunktion von std::ostreambuf_iterator<CharT,Traits>) [bearbeiten]
greift auf die aktuelle Übereinstimmung zu
(öffentliche Memberfunktion von std::regex_iterator<BidirIt,CharT,Traits>) [bearbeiten]
greift auf die aktuelle Teilübereinstimmung zu
(öffentliche Memberfunktion von std::regex_token_iterator<BidirIt,CharT,Traits>) [bearbeiten]

Keine Standardbibliotheksklassen überladen operator&. Das bekannteste Beispiel für überladenes operator& ist die Microsoft COM-Klasse CComPtr, obwohl es auch in EDSLs wie boost.spirit vorkommen kann.

Keine Standardbibliotheksklassen überladen operator->*. Es wurde vorgeschlagen, dass es Teil des Smart-Pointer-Interfaces sein könnte und in dieser Funktion von Akteuren in boost.phoenix verwendet wird, ist aber in EDSLs wie cpp.react häufiger anzutreffen.

[bearbeiten] Anmerkungen

Feature-Testmakro Wert Std Feature
__cpp_multidimensional_subscript 202110L (C++23) Mehrdimensionaler Indexoperator

[bearbeiten] Defektberichte

Die folgenden Verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.

DR angewendet auf Verhalten wie veröffentlicht Korrigiertes Verhalten
CWG 1213 C++11 Das Indizieren eines Array-Rvalues ergab ein lvalue wurde als xvalue klassifiziert
CWG 1458 C++98 das Anwenden von & auf ein lvalue eines unvollständigen Klassentyps, das
operator& deklariert, führte zu undefiniertem Verhalten
es ist nicht spezifiziert
welches & verwendet wird
CWG 1642 C++98 die rhs  in eingebauten Zeiger-auf-Member-Zugriffsoperatoren könnte ein lvalue sein kann nur ein rvalue sein
CWG 1800 C++98 beim Anwenden von & auf ein nicht-statisches Datenelement einer
Member-anonymen-Union, war es unklar, ob
die anonyme Union am Ergebnistyp beteiligt ist
die anonyme Union
ist nicht enthalten in
dem Ergebnistyp
CWG 2614 C++98 war das Ergebnis von E1.E2 unklar, wenn E2 ein Referenzmember oder ein Enumerator ist wurde klargestellt
CWG 2725 C++98 wenn E2 eine statische Memberfunktion ist, ist E1.E2 wohlgeformt
auch wenn es nicht der linke Operand von operator() ist
E1.E2 ist schlecht geformt
in diesem Fall
CWG 2748 C++98 war das Verhalten von E1->E2 unklar, wenn E1 ein
Nullzeiger ist und E2 auf ein statisches Mitglied verweist
Das Verhalten ist
in diesem Fall nicht definiert.
CWG 2813 C++98 war E1 keine verworfene Ausdrucksweise, wenn
E1.E2 ein statisches Mitglied oder eine Enumeration benennt
sie ist
CWG 2823 C++98 war das Verhalten von *expr unklar, wenn expr
nicht auf ein Objekt oder eine Funktion zeigt
wurde klargestellt

[bearbeiten] Siehe auch

Operatorrangfolge

Operatorüberladung

Häufige Operatoren
Zuweisung Inkrement
Dekrement
Arithmetik Logisch Vergleich Member
Zugriff
Sonstiges

a = b
a += b
a -= b
a *= b
a /= b
a %= b
a &= b
a |= b
a ^= b
a <<= b
a >>= b

++a
--a
a++
a--

+a
-a
a + b
a - b
a * b
a / b
a % b
~a
a & b
a | b
a ^ b
a << b
a >> b

!a
a && b
a || b

a == b
a != b
a < b
a > b
a <= b
a >= b
a <=> b

a[...]
*a
&a
a->b
a.b
a->*b
a.*b

Funktionsaufruf

a(...)
Komma

a, b
Ternär

a ? b : c
Spezielle Operatoren

static_cast konvertiert einen Typ in einen anderen verwandten Typ
dynamic_cast konvertiert innerhalb von Vererbungshierarchien
const_cast fügt cv-Qualifizierer hinzu oder entfernt sie
reinterpret_cast konvertiert einen Typ in einen nicht verwandten Typ
C-Stil Cast konvertiert einen Typ in einen anderen durch eine Mischung aus static_cast, const_cast und reinterpret_cast
new erstellt Objekte mit dynamischer Speicherverwaltung
delete zerstört zuvor mit new-Ausdruck erstellte Objekte und gibt den zugewiesenen Speicherbereich frei
sizeof fragt die Größe eines Typs ab
sizeof... fragt die Größe eines packs ab (seit C++11)
typeid fragt die Typinformationen eines Typs ab
noexcept prüft, ob ein Ausdruck eine Ausnahme auslösen kann (seit C++11)
alignof fragt die Ausrichtungsvoraussetzungen eines Typs ab (seit C++11)

C-Dokumentation für Member-Zugriffsoperatoren