Inkrement-/Dekrement-Operatoren
Inkrement-/Dekrement-Operatoren erhöhen oder verringern den Wert des Objekts.
| Operatorname | Syntax | Überladbar | Prototypenbeispiele (für class T) | |
|---|---|---|---|---|
| Innerhalb der Klassendefinition | Außerhalb der Klassendefinition | |||
| Präfix-Inkrement | ++a
|
Ja | T& T::operator++(); | T& operator++(T& a); |
| Präfix-Dekrement | --a
|
Ja | T& T::operator--(); | T& operator--(T& a); |
| Suffix-Inkrement | a++
|
Ja | T T::operator++(int); | T operator++(T& a, int); |
| Suffix-Dekrement | a--
|
Ja | T T::operator--(int); | T operator--(T& a, int); |
| ||||
Inhalt |
[edit] Präfix-Operatoren
Die Präfix-Inkrement- und Dekrement-Ausdrücke haben die Form
++ expression |
|||||||||
-- expression |
|||||||||
[edit] Eingebaute Präfix-Operatoren
|
(bis C++17) |
|
(seit C++17) |
|
(seit C++20) |
- Wenn der Typ von expression (möglicherweise cv-qualifiziert) bool ist, ist das Programm schlecht geformt.
|
(seit C++20) |
[edit] Überladungen
Bei der Überladungsauflösung für benutzerdefinierte Operatoren nehmen für jeden optional mit volatile qualifizierten arithmetischen Typ `A`, der kein bool ist, und für jeden optional mit volatile qualifizierten Zeiger `P` auf einen optional cv-qualifizierten Objekttyp die folgenden Funktionssignaturen an der Überladungsauflösung teil:
| A& operator++(A&) |
||
| bool& operator++(bool&) |
(veraltet)(bis C++17) | |
| P& operator++(P&) |
||
| A& operator--(A&) |
||
| P& operator--(P&) |
||
[edit] Suffix-Operatoren
Die Suffix-Inkrement- und Dekrement-Ausdrücke haben die Form
expression ++ |
|||||||||
expression -- |
|||||||||
[edit] Eingebaute Suffix-Operatoren
Das Ergebnis von Suffix-Inkrement oder -Dekrement ist der Wert, der durch Anwenden der Lvalue-zu-Rvalue-Konvertierung auf expression (vor der Modifikation) erhalten wird. Der Typ des Ergebnisses ist die cv-unqualifizierte Version des Typs von expression.
Wenn expression kein modifizierbarer Lvalue eines arithmetischen Typs ist außer (möglicherweise cv-qualifiziert) bool(seit C++17), oder ein Zeiger auf einen vollständigen Objekttyp, ist das Programm schlecht geformt.
|
Wenn der Typ von expression mit volatile qualifiziert ist, sind Inkrement oder Dekrement veraltet. |
(seit C++20) |
++ wäre.-- wäre.Die Wertberechnung eines Suffix-Inkrements oder -Dekrements erfolgt *vor* der Modifikation von expression. In Bezug auf einen beliebig sequenzierten Funktionsaufruf ist die Operation eines Suffix-Inkrements oder -Dekrements eine einzelne Auswertung.
[edit] Überladungen
Bei der Überladungsauflösung für benutzerdefinierte Operatoren nehmen für jeden optional mit volatile qualifizierten arithmetischen Typ `A`, der kein bool ist, und für jeden optional mit volatile qualifizierten Zeiger `P` auf einen optional cv-qualifizierten Objekttyp die folgenden Funktionssignaturen an der Überladungsauflösung teil:
| A operator++(A&, int) |
||
| bool operator++(bool&, int) |
(veraltet)(bis C++17) | |
| P operator++(P&, int) |
||
| A operator--(A&, int) |
||
| P operator--(P&, int) |
||
[edit] Beispiel
#include <iostream> int main() { int n1 = 1; int n2 = ++n1; int n3 = ++ ++n1; int n4 = n1++; // int n5 = n1++ ++; // error // int n6 = n1 + ++n1; // undefined behavior std::cout << "n1 = " << n1 << '\n' << "n2 = " << n2 << '\n' << "n3 = " << n3 << '\n' << "n4 = " << n4 << '\n'; }
Ausgabe
n1 = 5 n2 = 2 n3 = 4 n4 = 4
[edit] Hinweise
Aufgrund der beteiligten Nebeneffekte müssen eingebaute Inkrement- und Dekrement-Operatoren mit Vorsicht verwendet werden, um undefiniertes Verhalten durch Verletzung von Sequenzierungsregeln zu vermeiden.
Da bei Suffix-Inkrement und -Dekrement eine temporäre Kopie des Objekts erstellt wird, sind Präfix-Inkrement- oder -Dekrement-Operatoren in Kontexten, in denen der zurückgegebene Wert nicht verwendet wird, in der Regel effizienter.
[edit] Standardbibliothek
Inkrement- und Dekrement-Operatoren sind für viele Standardbibliothekstypen überladen. Insbesondere überlädt jeder LegacyIterator operator++ und jeder LegacyBidirectionalIterator operator--, auch wenn diese Operatoren für den jeweiligen Iterator keine Operationen sind.
Überladungen für arithmetische Typen | |
| inkrementiert oder dekrementiert den atomaren Wert um eins (öffentliche Memberfunktion von std::atomic<T>) | |
| inkrementiert oder dekrementiert die Tick-Anzahl (öffentliche Memberfunktion von std::chrono::duration<Rep,Period>) | |
Überladungen für Iteratortypen | |
| bewegt den Iterator vorwärts (öffentliche Memberfunktion von std::raw_storage_iterator<OutputIt,T>) | |
bewegt den reverse_iterator vorwärts oder rückwärts(öffentliche Memberfunktion von std::reverse_iterator<Iter>) | |
bewegt den move_iterator vorwärts oder rückwärts(öffentliche Memberfunktion von std::move_iterator<Iter>) | |
| no-op (öffentliche Memberfunktion von std::front_insert_iterator<Container>) | |
| no-op (öffentliche Memberfunktion von std::back_insert_iterator<Container>) | |
| no-op (öffentliche Memberfunktion von std::insert_iterator<Container>) | |
| bewegt den Iterator vorwärts (öffentliche Memberfunktion von std::istream_iterator<T,CharT,Traits,Distance>) | |
| no-op (öffentliche Memberfunktion von std::ostream_iterator<T,CharT,Traits>) | |
| bewegt den Iterator vorwärts (öffentliche Memberfunktion von std::istreambuf_iterator<CharT,Traits>) | |
| no-op (öffentliche Memberfunktion von std::ostreambuf_iterator<CharT,Traits>) | |
| bewegt den Iterator zum nächsten Treffer (öffentliche Memberfunktion von std::regex_iterator<BidirIt,CharT,Traits>) | |
| bewegt den Iterator zum nächsten Teilübereinstimmung (öffentliche Memberfunktion von std::regex_token_iterator<BidirIt,CharT,Traits>) | |
[edit] Fehlerberichte
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 2855 | C++98 | Die üblichen arithmetischen Konvertierungen werden für eingebaute Präfix-Inkrementierung und Präfix-Dekrementierung angewendet, wurden aber nicht für ihre Suffix-Gegenstücke angewendet[1] |
auch angewendet |
| CWG 2901 | C++98 | Lvalue-zu-Rvalue-Konvertierungen wurden nicht angewendet für eingebaute Suffix-Inkrementierung und Suffix-Dekrementierung |
angewendet |
- ↑ Der Präfix-Operator ++x ist äquivalent zu x += 1, und letzteres ist für übliche arithmetische Konvertierungen anwendbar (d. h. es ergibt einen gemeinsamen Typ zwischen decltype(x) und int). Der Effekt des Suffix-Operators x++ ist jedoch einfach das "Hinzufügen von eins zu x", es gibt keinen binären Operator, sodass keine üblichen arithmetischen Konvertierungen stattfinden.
[edit] Siehe auch
| Häufige Operatoren | ||||||
|---|---|---|---|---|---|---|
| Zuweisung | Inkrement Dekrement |
Arithmetik | Logisch | Vergleich | Member Zugriff |
Sonstiges |
|
a = b |
++a |
+a |
!a |
a == b |
a[...] |
Funktionsaufruf a(...) |
| Komma a, b | ||||||
| Ternär a ? b : c | ||||||
| Spezielle Operatoren | ||||||
|
static_cast konvertiert einen Typ in einen anderen verwandten Typ | ||||||
| C-Dokumentation für Inkrement-/Dekrement-Operatoren
|