Other operators
|
Operator
Name |
Syntax | Überladbar | Prototyp-Beispiele (für class T ) | |
|---|---|---|---|---|
| Innerhalb der Klassendefinition | Außerhalb der Klassendefinition | |||
| Funktionsaufruf |
a(a1, a2)
|
Ja | R T :: operator ( ) ( Arg1 & a1, Arg2 & a2, ... ) ; | N/A |
| Komma |
a, b
|
Ja | T2 & T :: operator , ( T2 & b ) ; | T2 & operator, ( const T & a, T2 & b ) ; |
| Bedingungsoperator |
a ? b : c
|
Nein | N/A | N/A |
Der Funktionsaufruf Operator bietet Funktionssemantik für jedes Objekt.
Der conditional operator (umgangssprachlich auch als ternary conditional bezeichnet) überprüft den booleschen Wert des ersten Ausdrucks und wertet abhängig vom resultierenden Wert entweder den zweiten oder den dritten Ausdruck aus und gibt diesen zurück.
Inhaltsverzeichnis |
Eingebauter Funktionsaufrufoperator
Funktionsaufrufausdrücke haben die folgende Form:
Funktion
(
arg1
,
arg2
,
arg3
,
...
)
|
|||||||||
| function | - | ein Ausdrucksfunktionstyp oder Funktionszeigertyp |
arg1
,
arg2
,
arg3
,
...
|
- | eine möglicherweise leere Liste beliebiger Ausdrücke oder geschweifte Klammer-Initialisierungslisten (seit C++11) , wobei der Komma-Operator auf oberster Ebene nicht zulässig ist, um Mehrdeutigkeiten zu vermeiden |
Für einen Aufruf einer Nicht-Member-Funktion oder einer static member function , function kann ein Lvalue sein, das auf eine Funktion verweist (in diesem Fall wird die function-to-pointer conversion unterdrückt), oder ein Prvalue vom Typ Funktionszeiger.
Der durch function spezifizierte Funktions- (oder Member-) Name kann überladen werden, Overload Resolution Regeln werden verwendet, um zu entscheiden, welche Überladung aufgerufen werden soll.
Wenn function eine Memberfunktion spezifiziert, kann sie virtuell sein, in welchem Fall der endgültige Überschreiber dieser Funktion aufgerufen wird, wobei dynamische Bindung zur Laufzeit verwendet wird.
Jeder Funktionsparameter wird mit seinem entsprechenden Argument initialisiert, nachdem implizite Konvertierung falls notwendig durchgeführt wurde.
- Wenn kein entsprechender Argument vorhanden ist, wird das entsprechende Standardargument verwendet, und falls keines vorhanden ist, ist das Programm fehlerhaft.
- Wenn der Aufruf an eine Elementfunktion erfolgt, wird der this -Zeiger auf das aktuelle Objekt wie durch eine explizite Umwandlung in den this -Zeiger konvertiert, den die Funktion erwartet.
- Die Initialisierung und Zerstörung jedes Parameters erfolgt im Kontext des vollständigen Ausdrucks , in dem der Funktionsaufruf erscheint, was bedeutet, dass, wenn ein Konstruktor oder Destruktor eines Parameters eine Ausnahme auslöst, die Funktions- try -Blöcke der aufgerufenen Funktion nicht berücksichtigt werden.
Wenn die Funktion eine variadische Funktion ist, default argument promotions werden auf alle Argumente angewendet, die durch den Ellipsenparameter abgedeckt sind.
Es ist implementierungsdefiniert, ob ein Parameter zerstört wird, wenn die Funktion, in der er definiert ist, verlassen wird, oder am Ende des umschließenden vollständigen Ausdrucks. Parameter werden immer in umgekehrter Reihenfolge ihrer Konstruktion zerstört.
Der Rückgabetyp eines Funktionsaufrufausdrucks ist der Rückgabetyp der gewählten Funktion, ermittelt durch statische Bindung (unter Ignorierung des virtual -Schlüsselworts), selbst wenn die überschriebene Funktion, die tatsächlich aufgerufen wird, einen anderen Typ zurückgibt. Dies erlaubt es den überschreibenden Funktionen, Zeiger oder Referenzen auf Klassen zurückzugeben, die von dem durch die Basis-Funktion zurückgegebenen Typ abgeleitet sind, d.h. C++ unterstützt kovariante Rückgabetypen . Wenn function einen Destruktor spezifiziert, ist der Rückgabetyp void .
|
Wenn ein Objekt vom Klassentyp
Das temporäre Objekt wird jeweils aus dem Funktionsargument oder Rückgabewert konstruiert, und der Funktionsparameter oder das Rückgabeobjekt wird initialisiert, als ob der nicht gelöschte triviale Konstruktor verwendet würde, um das temporäre Objekt zu kopieren (selbst wenn dieser Konstruktor unzugänglich ist oder durch Overload Resolution nicht zur Ausführung einer Kopie oder Verschiebung des Objekts ausgewählt werden würde). Dies ermöglicht es, Objekte kleiner Klassentypen, wie std::complex oder std::span , in Registern an Funktionen zu übergeben oder von Funktionen zurückzugeben. |
(since C++17) |
Der Wertkategorie eines Funktionsaufrufausdrucks ist L-Wert, wenn die Funktion eine L-Wert-Referenz oder eine R-Wert-Referenz auf Funktion zurückgibt, ist ein X-Wert, wenn die Funktion eine R-Wert-Referenz auf Objekt zurückgibt, und ist ein PR-Wert andernfalls. Wenn der Funktionsaufrufausdruck ein PR-Wert von Objekttyp ist, muss er einen
vollständigen Typ
haben, außer wenn er als Operand von
decltype
verwendet wird (oder als rechter Operand eines
eingebauten Komma-Operators
, der der Operand von
decltype
ist)
(seit C++11)
.
|
Wenn die aufgerufene Funktion normal beendet wird, werden alle
Postcondition-Assertions
der Funktion
in Sequenz ausgewertet
. Falls die Implementierung
temporäre Objekte
zur Aufnahme des Ergebniswerts einführt, gilt für die Auswertung
|
(seit C++26) |
Funktionsaufrufausdrücke sind syntaktisch ähnlich zur Wertinitialisierung
T
(
)
, zum
funktionsstil Cast
-Ausdruck
T
(
A1
)
, und zur direkten Initialisierung eines temporären Objekts
T
(
A1, A2, A3, ...
)
, wobei
T
der Name eines Typs ist.
#include <cstdio> struct S { int f1(double d) { return printf("%f \n", d); // variable argument function call } int f2() { return f1(7); // member function call, same as this->f1() // integer argument converted to double } }; void f() { puts("function called"); // function call } int main() { f(); // function call S s; s.f2(); // member function call }
Ausgabe:
function called 7.000000
Eingebauter Komma-Operator
Komma-Ausdrücke haben die folgende Form:
E1
,
E2
|
|||||||||
In einem Komma-Ausdruck
E1, E2
wird der Ausdruck
E1
ausgewertet, sein Ergebnis wird
verworfen
(obwohl, falls er einen Klassentyp hat, er nicht zerstört wird
bis zum Ende des umschließenden vollständigen Ausdrucks
), und seine Nebeneffekte werden abgeschlossen, bevor die Auswertung des Ausdrucks
E2
beginnt
(beachten Sie, dass ein benutzerdefinierter
operator,
keine Sequenzierung garantieren kann)
(bis C++17)
.
Der Typ, Wert und die Wertkategorie des Ergebnisses des Komma-Ausdrucks entsprechen exakt dem Typ, Wert und der Wertkategorie des zweiten Operanden, E2 . Wenn E2 ein temporärer Ausdruck (seit C++17) ist, ist das Ergebnis des Ausdrucks dieser temporäre Ausdruck (seit C++17) . Wenn E2 ein Bitfeld ist, ist das Ergebnis ein Bitfeld.
Das Komma in verschiedenen durch Kommata getrennten Listen, wie Funktionsargumentlisten ( f ( a, b, c ) ) und Initialisierungslisten int a [ ] = { 1 , 2 , 3 } , ist nicht der Komma-Operator. Wenn der Komma-Operator in solchen Kontexten verwendet werden muss, muss er in Klammern gesetzt werden: f ( a, ( n ++ , n + b ) , c ) .
|
Die Verwendung eines nicht in Klammern gesetzten Kommaausdrucks als zweites (rechtes) Argument eines Subskriptoperators ist veraltet. Beispielsweise ist a [ b, c ] veraltet und a [ ( b, c ) ] ist es nicht. |
(seit C++20)
(bis C++23) |
|
Ein nicht in Klammern gesetzter Kommaausdruck kann nicht zweites (rechtes) Argument eines Subskriptoperators sein. Beispielsweise ist a [ b, c ] entweder fehlerhaft oder äquivalent zu a. operator [ ] ( b, c ) . Klammern sind erforderlich, wenn ein Kommaausdruck als Subskript verwendet wird, z.B. a [ ( b, c ) ] . |
(seit C++23) |
#include <iostream> int main() { // Komma wird oft verwendet, um mehr als einen Ausdruck auszuführen // wo die Sprachgrammatik nur einen Ausdruck erlaubt: // * in der dritten Komponente der for-Schleife for (int i = 0, j = 10; i <= j; ++i, --j) // ^Listen-Trennzeichen ^Komma-Operator std::cout << "i = " << i << " j = " << j << '\n'; // * in einer return-Anweisung // return log("an error!"), -1; // * in einem Initialisierungsausdruck // MyClass(const Arg& arg) // : member{ throws_if_bad(arg), arg } // usw. // Komma-Operatoren können verkettet werden; das Ergebnis des letzten // (rechtesten) Ausdrucks ist das Ergebnis der gesamten Kette: int n = 1; int m = (++n, std::cout << "n = " << n << '\n', ++n, 2 * n); // m ist jetzt 6 std::cout << "m = " << (++m, m) << '\n'; }
Ausgabe:
i = 0 j = 10 i = 1 j = 9 i = 2 j = 8 i = 3 j = 7 i = 4 j = 6 i = 5 j = 5 n = 2 m = 7
Bedingter Operator
Die bedingten Operatorausdrücke haben die Form
E1
?
E2
:
E3
|
|||||||||
E1 wird ausgewertet und kontextuell konvertiert zu bool . Wenn das Ergebnis true ist, dann ist das Ergebnis des bedingten Ausdrucks der Wert von E2 ; andernfalls ist das Ergebnis des bedingten Ausdrucks der Wert von E3 .
Der Typ und die Wertkategorie des bedingten Ausdrucks E1 ? E2 : E3 werden wie folgt bestimmt:
Stufe 1
Wenn sowohl E2 als auch E3 vom Typ void sind, ist das Ergebnis ein R-Wert (bis C++11) ein PR-Wert (seit C++11) vom Typ void .
Wenn genau einer von E2 und E3 vom Typ void ist:
- Wenn dieser Operand vom Typ void ein (möglicherweise in Klammern gesetzter) throw Ausdruck ist, hat das Ergebnis den Typ und die Wertkategorie des anderen Operanden [1] . Wenn der andere Operand ein Bit-Feld ist, ist das Ergebnis ebenfalls ein Bit-Feld.
- Andernfalls ist das Programm fehlerhaft.
Wenn keiner von E2 und E3 vom Typ void ist, fahren Sie mit der nächsten Stufe fort.
2 + 2 == 4 ? throw 123 : throw 456; // das Ergebnis ist vom Typ „void“ 2 + 2 != 4 ? "OK" : throw "error"; // das Ergebnis ist vom Typ „const char[3]“ // selbst wenn immer eine Exception ausgelöst wird
Stufe 2
Wenn
E2
oder
E3
Lvalue-Bitfelder
(bis C++11)
Glvalue-Bitfelder derselben Wertkategorie
(seit C++11)
und von den Typen
cv1
T
bzw.
cv2
T
sind, werden die Operanden für den weiteren Prozess als vom Typ
cv
T
betrachtet, wobei
cv
die Vereinigung von
cv1
und
cv2
ist.
Wenn E2 und E3 unterschiedliche Typen haben und eine der folgenden Bedingungen erfüllt ist, fahren Sie mit Stufe 3 fort:
- Mindestens einer von E2 und E3 ist ein (möglicherweise cv-qualifizierter) Klassentyp.
- Beide von E2 und E3 sind Lvalues desselben Typs (bis C++11) Glvalues derselben Wertkategorie und desselben Typs (seit C++11) mit Ausnahme der CV-Qualifikation.
Andernfalls fahren Sie mit Stufe 4 fort.
Stufe 3
Es wird versucht, eine
implizite Konvertierungssequenz
[2]
von einem Operandenausdruck
X
vom Typ
TX
zu einem
Zieltyp
zu bilden, der mit dem Typ
TY
des Operandenausdrucks
Y
wie folgt zusammenhängt:
-
Wenn
Y
ein Lvalue ist, ist der Zieltyp
TY&, aber eine implizite Konvertierungssequenz kann nur gebildet werden, wenn die Referenz direkt bindet an einen Lvalue (bis C++11) einen Glvalue (seit C++11) .
|
(seit C++11) |
-
Wenn
Y
ein
R-Wert
(bis C++11)
PR-Wert
(seit C++11)
ist oder wenn keine der oben genannten Konvertierungssequenzen gebildet werden kann und mindestens einer der Typen
TXundTYein (möglicherweise cv-qualifizierter) Klassentyp ist:-
Wenn
TXundTYdenselben Klassentyp haben (unter Ignorierung der CV-Qualifizierung):-
Wenn
TYmindestens so cv-qualifiziert ist wieTX, ist der ZieltypTY. - Andernfalls wird keine Konvertierungssequenz gebildet.
-
Wenn
-
Andernfalls, wenn
TYeine Basisklasse vonTXist, ist der ZieltypTYmit den CV-Qualifizierern vonTX. - Andernfalls ist der Zieltyp der Typ von Z , wobei Z der Wert von Y nach Anwendung der Standardkonvertierungen L-Wert-zu-R-Wert, Array-zu-Zeiger und Funktion-zu-Zeiger ist.
-
Wenn
- Andernfalls wird keine Konvertierungssequenz gebildet.
Mit diesem Prozess wird bestimmt, ob eine implizite Konvertierungssequenz von E2 zum Zieltyp, der für E3 bestimmt wurde, gebildet werden kann, und umgekehrt.
- Falls keine Konvertierungssequenz gebildet werden kann, fahre mit der nächsten Stufe fort.
-
Falls genau eine Konvertierungssequenz gebildet werden kann:
- Wenn die Konvertierungssequenz mehrdeutig ist, ist das Programm fehlerhaft.
- Andernfalls wird diese Konvertierung auf den gewählten Operanden angewendet und der konvertierte Operand wird anstelle des ursprünglichen Operanden für den weiteren Prozess verwendet, und es wird mit der nächsten Stufe fortgefahren.
- Falls beide Sequenzen gebildet werden können, ist das Programm fehlerhaft.
struct A {}; struct B : A {}; using T = const B; A a = true ? A() : T(); // Y = A(), TY = A, X = T(), TX = const B, Ziel = const A
Stufe 4
|
Wenn E2 und E3 Lvalues desselben Typs sind, dann ist das Ergebnis ein Lvalue desselben Typs und ein Bitfeld, falls mindestens einer von E2 und E3 ein Bitfeld ist. |
(bis C++11) |
|
Wenn E2 und E3 Glvalues desselben Typs und derselben Wertkategorie sind, dann hat das Ergebnis denselben Typ und dieselbe Wertkategorie und ist ein Bitfeld, falls mindestens einer von E2 und E3 ein Bitfeld ist. |
(seit C++11) |
Andernfalls ist das Ergebnis an rvalue (until C++11) a prvalue (since C++11) .
- Wenn E2 und E3 nicht denselben Typ haben und einer von beiden (möglicherweise cv-qualifizierten) Klassentyp besitzt, fahren Sie mit Stufe 5 fort.
- Andernfalls fahren Sie mit Stufe 6 fort.
Stufe 5
Overload resolution wird unter Verwendung der built-in candidates durchgeführt, um zu versuchen, die Operanden in Built-in-Typen zu konvertieren:
- Wenn die Überladungsauflösung fehlschlägt, ist das Programm fehlerhaft.
- Andernfalls werden die ausgewählten Konvertierungen angewendet und die konvertierten Operanden werden anstelle der ursprünglichen Operanden für den weiteren Prozess verwendet. Fahren Sie mit der nächsten Stufe fort.
Stufe 6
Die Array-zu-Zeiger- und Funktion-zu-Zeiger-Konvertierungen werden auf (möglicherweise konvertierte) E2 und E3 angewendet. Nach diesen Konvertierungen muss mindestens eine der folgenden Bedingungen erfüllt sein, andernfalls ist das Programm fehlerhaft:
- E2 und E3 haben denselben Typ. In diesem Fall ist das Ergebnis von diesem Typ und wird mittels Copy-Initialisierung unter Verwendung des ausgewählten Operanden initialisiert.
- Sowohl E2 als auch E3 haben arithmetischen oder Aufzählungstyp. In diesem Fall werden übliche arithmetische Konvertierungen angewendet, um sie auf ihren gemeinsamen Typ zu bringen, und das Ergebnis ist von diesem Typ.
- Mindestens einer der Operanden E2 und E3 ist ein Zeiger. In diesem Fall werden Lvalue-zu-Rvalue-, Zeiger- , Funktionszeiger (seit C++17) und Qualifikationskonvertierungen angewendet, um sie auf ihren zusammengesetzten Zeigertyp zu bringen, und das Ergebnis ist von diesem Typ.
- Mindestens einer der Operanden E2 und E3 ist ein Elementzeiger. In diesem Fall werden Lvalue-zu-Rvalue-, Elementzeiger- , Funktionszeiger (seit C++17) und Qualifikationskonvertierungen angewendet, um sie auf ihren zusammengesetzten Zeigertyp zu bringen, und das Ergebnis ist von diesem Typ.
|
(seit C++11) |
int* intPtr; using Mixed = decltype(true ? nullptr : intPtr); static_assert(std::is_same_v<Mixed, int*>); // nullptr wird zu int* struct A { int* m_ptr; } a; int* A::* memPtr = &A::m_ptr; // memPtr ist ein Zeiger auf Element m_ptr von A // memPtr macht nullptr zum Typ Zeiger auf Element m_ptr von A static_assert(std::is_same_v<decltype(false ? memPtr : nullptr), int*A::*>); // a.*memPtr ist jetzt nur Zeiger auf int und nullptr wird ebenfalls zu Zeiger auf int static_assert(std::is_same_v<decltype(false ? a.*memPtr : nullptr), int*>);
- ↑ Solcher bedingte Operator wurde häufig in C++11 constexpr-Programmierung vor C++14 verwendet.
- ↑ Member-Zugriff , ob eine Konvertierungsfunktion gelöscht ist (seit C++11) und ob ein Operand ein Bitfeld ist, werden ignoriert.
|
Der Ergebnistyp eines bedingten Operators ist auch als binäres Typ-Merkmal std::common_type zugänglich. |
(since C++11) |
Überladungen
Für jedes Paar von heraufgestuften arithmetischen Typen
L
und
R
und für jeden Typ
P
, wobei
P
ein Zeiger, Zeiger-auf-Mitglied oder ein scoped enumeration Typ ist, nehmen die folgenden Funktionssignaturen an der Überlagerungsauflösung teil:
|
LR-Operator
?:
(
bool
, L, R
)
;
|
||
|
P-Operator
?:
(
bool
, P, P
)
;
|
||
wobei LR das Ergebnis der
üblichen arithmetischen Konvertierungen
ist, die auf
L
und
R
angewendet werden.
Der Operator „
?:
“ kann nicht überladen werden, diese Funktionssignaturen existieren nur zum Zweck der Überladungsauflösung.
#include <iostream> #include <string> struct Node { Node* next; int data; // deep-copying copy constructor Node(const Node& other) : next(other.next ? new Node(*other.next) : NULL) , data(other.data) {} Node(int d) : next(NULL), data(d) {} ~Node() { delete next; } }; int main() { // simple rvalue example int n = 1 > 2 ? 10 : 11; // 1 > 2 is false, so n = 11 // simple lvalue example int m = 10; (n == m ? n : m) = 7; // n == m is false, so m = 7 //output the result std::cout << "n = " << n << "\nm = " << m; }
Ausgabe:
n = 11 m = 7
Standardbibliothek
Viele Klassen in der Standardbibliothek überladen
operator()
um als Funktionsobjekte verwendet zu werden.
|
löscht das Objekt oder Array
(öffentliche Elementfunktion von
std::default_delete<T>
)
|
|
|
gibt die Summe zweier Argumente zurück
(öffentliche Elementfunktion von
std::plus<T>
)
|
|
|
gibt die Differenz zwischen zwei Argumenten zurück
(öffentliche Mitgliedsfunktion von
std::minus<T>
)
|
|
|
gibt das Produkt zweier Argumente zurück
(öffentliche Elementfunktion von
std::multiplies<T>
)
|
|
|
gibt das Ergebnis der Division des ersten Arguments durch das zweite Argument zurück
(öffentliche Elementfunktion von
std::divides<T>
)
|
|
|
gibt den Rest der Division des ersten Arguments durch das zweite Argument zurück
(öffentliche Elementfunktion von
std::modulus<T>
)
|
|
|
gibt die Negation des Arguments zurück
(öffentliche Elementfunktion von
std::negate<T>
)
|
|
|
prüft, ob die Argumente gleich sind
(öffentliche Elementfunktion von
std::equal_to<T>
)
|
|
|
prüft, ob die Argumente ungleich sind
(öffentliche Elementfunktion von
std::not_equal_to<T>
)
|
|
|
prüft, ob das erste Argument größer als das zweite ist
(öffentliche Elementfunktion von
std::greater<T>
)
|
|
|
prüft, ob das erste Argument kleiner als das zweite ist
(öffentliche Elementfunktion von
std::less<T>
)
|
|
|
prüft, ob das erste Argument größer oder gleich dem zweiten ist
(öffentliche Elementfunktion von
std::greater_equal<T>
)
|
|
|
prüft, ob das erste Argument kleiner oder gleich dem zweiten ist
(öffentliche Elementfunktion von
std::less_equal<T>
)
|
|
|
gibt das logische UND der beiden Argumente zurück
(öffentliche Elementfunktion von
std::logical_and<T>
)
|
|
|
gibt das logische ODER der beiden Argumente zurück
(öffentliche Elementfunktion von
std::logical_or<T>
)
|
|
|
gibt das logische NOT des Arguments zurück
(öffentliche Elementfunktion von
std::logical_not<T>
)
|
|
|
gibt das Ergebnis der bitweisen UND-Verknüpfung zweier Argumente zurück
(öffentliche Mitgliedsfunktion von
std::bit_and<T>
)
|
|
|
gibt das Ergebnis der bitweisen ODER-Verknüpfung zweier Argumente zurück
(öffentliche Elementfunktion von
std::bit_or<T>
)
|
|
|
gibt das Ergebnis der bitweisen XOR-Operation zweier Argumente zurück
(öffentliche Mitgliedsfunktion von
std::bit_xor<T>
)
|
|
|
gibt das logische Komplement des Ergebnisses eines Aufrufs des gespeicherten Prädikats zurück
(öffentliche Elementfunktion von
std::unary_negate<Predicate>
)
|
|
|
gibt das logische Komplement des Ergebnisses eines Aufrufs des gespeicherten Prädikats zurück
(öffentliche Elementfunktion von
std::binary_negate<Predicate>
)
|
|
|
ruft die gespeicherte Funktion auf
(öffentliche Elementfunktion von
std::reference_wrapper<T>
)
|
|
|
ruft das Zielobjekt auf
(öffentliche Elementfunktion von
std::function<R(Args...)>
)
|
|
|
ruft das Zielobjekt auf
(öffentliche Elementfunktion von
std::move_only_function
)
|
|
|
ruft das Zielobjekt auf
(öffentliche Elementfunktion von
std::copyable_function
)
|
|
|
setzt die Ausführung der Coroutine fort
(öffentliche Mitgliedsfunktion von
std::coroutine_handle<Promise>
)
|
|
|
vergleicht zwei Zeichenketten lexikographisch unter Verwendung des Collate-Facets dieser Locale
(öffentliche Elementfunktion von
std::locale
)
|
|
vergleicht zwei Werte vom Typ
value_type
(öffentliche Elementfunktion von
std::map<Key,T,Compare,Allocator>::value_compare
)
|
|
vergleicht zwei Werte vom Typ
value_type
(öffentliche Elementfunktion von
std::multimap<Key,T,Compare,Allocator>::value_compare
)
|
|
|
führt die Funktion aus
(öffentliche Elementfunktion von
std::packaged_task<R(Args...)>
)
|
|
|
setzt den Zustand der Engine fort und gibt den generierten Wert zurück
(öffentliche Elementfunktion von
std::linear_congruential_engine<UIntType,a,c,m>
)
|
|
|
(C++11)
|
generiert die nächste Zufallszahl in der Verteilung
(öffentliche Elementfunktion von
std::uniform_int_distribution<IntType>
)
|
Der Komma-Operator wird von keiner Klasse in der Standardbibliothek überladen. Die Boost-Bibliothek verwendet operator, in boost.assign , boost.spirit und anderen Bibliotheken. Die Datenbankzugriffsbibliothek SOCI überlädt ebenfalls operator, .
Fehlerberichte
Die folgenden verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.
| DR | Angewendet auf | Verhalten wie veröffentlicht | Korrektes Verhalten |
|---|---|---|---|
| CWG 446 | C++98 |
es war nicht spezifiziert, ob für eine Lvalue-zu-Rvalue-Konvertierung beim
Bedingungsoperator ein Temporärobjekt erzeugt wird |
erzeugt immer ein Temporärobjekt, wenn
der Operator einen Klassen-Rvalue zurückgibt |
| CWG 462 | C++98 |
wenn der zweite Operand eines Kommaoperators ein Temporärobjekt ist,
war nicht spezifiziert, ob seine Lebensdauer verlängert wird, wenn das Ergebnis des Kommaausdrucks an eine Referenz gebunden wird |
das Ergebnis des Kommaausdrucks
ist in diesem Fall das Temporärobjekt (daher wird seine Lebensdauer verlängert) |
| CWG 587 | C++98 |
wenn der zweite und dritte Operand eines Bedingungsoperators
Lvalues desselben Typs außer CV-Qualifizierung sind, war das Ergebnis ein Lvalue, wenn diese Operanden Klassentypen haben, andernfalls ein Rvalue |
das Ergebnis ist in diesem Fall
immer ein Lvalue |
| CWG 1029 | C++98 | der Typ eines Destruktoraufrufs war nicht spezifiziert | spezifiziert als void |
| CWG 1550 | C++98 |
geklammerte
throw
-Ausdrücke waren in bedingten Ausdrücken
nicht erlaubt, wenn der andere Operand nicht- void ist |
akzeptiert |
| CWG 1560 | C++98 |
void
-Operand von Bedingungsoperatoren verursachte
unnötige Lvalue-zu-Rvalue-Konvertierung beim anderen Operanden, was immer zu einem Rvalue führte |
ein bedingter Ausdruck
mit einem void kann ein Lvalue sein |
| CWG 1642 | C++98 |
der Ausdruck
function
in einem Funktionsaufruf-
ausdruck konnte ein Funktionszeiger-Lvalue sein |
nicht erlaubt |
| CWG 1805 | C++98 |
bei der Bestimmung des Zieltyps für die implizite Konvertierungs-
sequenz war die Art der Konvertierung von Y zu Z unklar |
klargestellt |
| CWG 1895 |
C++98
C++11 |
unklar, ob gelöschte (C++11) oder unzugängliche (C++98)
Konvertierungsfunktionen die Konvertierung in bedingten Ausdrücken verhindern, und Konvertierungen von Basisklasse zu abgeleiteter Klassen-Prvalue wurden nicht berücksichtigt |
behandelt wie
Überladungsauflösung |
| CWG 1932 | C++98 | Bitfelder desselben Typs fehlten in bedingten Ausdrücken | behandelt durch zugrundeliegende Typen |
| CWG 2226 | C++11 |
bei der Bestimmung des Zieltyps des anderen
Operanden eines Bedingungsoperators konnte Referenz nicht an einen Xvalue binden, wenn dieser Operand ein Lvalue ist |
erlaubt |
| CWG 2283 | C++17 |
die Typvollständigkeitsanforderung für den Funktionsaufruf-
operator wurde versehentlich durch P0135R1 entfernt |
stellte die Anforderung wieder her |
| CWG 2321 | C++98 |
bei der Bestimmung des Zieltyps des anderen Operanden
eines Bedingungsoperators konnte ein abgeleiteter Klassentyp nicht in einen weniger CV-qualifizierten Basisklassentyp konvertiert werden |
erlaubt Konvertierung zum Basis-
klassentyp mit der CV-Qualifizierung vom abgeleiteten Klassenoperanden |
| CWG 2715 | C++98 |
die Initialisierung und Zerstörung jedes
Parameters würde im Kontext der aufrufenden Funktion erfolgen, die möglicherweise nicht existiert [1] |
erfolgt im Kontext des
umschließenden vollständigen Ausdrucks |
| CWG 2850 | C++98 | die Zerstörungsreihenfolge von Parametern war unklar | klargestellt |
| CWG 2865 | C++98 |
wenn
TX
und
TY
denselben Klassentyp haben und
TX
stärker CV-qualifiziert ist als
TY
, könnte eine implizite
Konvertierungssequenz trotzdem von einem Prvalue Y gebildet werden |
in diesem Fall wird keine
Konvertierungssequenz gebildet |
| CWG 2906 | C++98 |
Lvalue-zu-Rvalue-Konvertierungen wurden bedingungslos angewendet
im Rvalue-Ergebnisfall für den Bedingungsoperator |
nur in einigen Fällen angewendet |
- ↑ Beispielsweise können Funktionen im Initialisierer einer Namespace-Variablen aufgerufen werden, es gibt in diesem Kontext keine "aufrufende Funktion".
Siehe auch
Operator-Präzedenz
Operator-Überladung
| Häufig verwendete Operatoren | ||||||
|---|---|---|---|---|---|---|
| Zuweisung |
Inkrement
Dekrement |
Arithmetik | Logisch | Vergleich |
Member
Zugriff |
Sonstige |
|
a
=
b
|
++
a
|
+
a
|
!
a
|
a
==
b
|
a
[
...
]
|
Funktionsaufruf
a ( ... ) |
|
Komma
a, b |
||||||
|
Bedingungsoperator
a ? b : c |
||||||
| Spezielle Operatoren | ||||||
|
static_cast
konvertiert einen Typ in einen anderen verwandten Typ
|
||||||
|
C-Dokumentation
für
Andere Operatoren
|