Alle C ++ - Operatoren, mit denen ich gearbeitet habe, geben etwas zurück, z. B. gibt der +
Operator das Ergebnis der Addition zurück.
Geben alle C ++ - Operatoren etwas zurück oder gibt es einige C ++ - Operatoren, die nichts zurückgeben?
Alle C ++ - Operatoren, mit denen ich gearbeitet habe, geben etwas zurück, z. B. gibt der +
Operator das Ergebnis der Addition zurück.
Geben alle C ++ - Operatoren etwas zurück oder gibt es einige C ++ - Operatoren, die nichts zurückgeben?
+=
Rückgabe implementieren void
, dies wird jedoch nicht empfohlen. Auch Funktionsaufrufbetreiber können zurückkehren void
und dies ist gültig
::
nichts zurückgibt, aber ich müsste den Standard konsultieren, um sicherzugehen.
Antworten:
Obwohl sie wahrscheinlich nicht genau das sind , woran Sie denken, beachten Sie, dass die Schlüsselwörter delete
und delete[]
C ++ tatsächlich Operatoren sind . und sie sind so definiert, dass sie den void
Rückgabetyp haben - was bedeutet, dass sie nichts auswerten (was nicht 'etwas' ist).
Aus der Referenz :
void operator delete ( void* ptr ) noexcept;
void operator delete[]( void* ptr ) noexcept;
delete
, delete[]
, throw
, (void)x;
Gegossen, linken Seite des ,
Bedieners, rechten Seite der ,
Bedienperson, dass ergibt eine void
a, ?:
ternäre , die eine verwendet throw
für einen der Arme, dfri ist operator void()
(wäre benutzerdefiniert) eingelegt ,眠りネロク's void operator()()
(die Benutzer festgelegt werden würde).
delete
Operator das Objekt zerstört und dann aufruft operator delete
. Ergo, der delete
Betreiber und operator delete
sind getrennte Dinge :( stackoverflow.com/a/8918942/845092
operator delete
.
Operatoren von benutzerdefinierten Typen können überlastet werden, um die seltsamsten Dinge zu tun.
Beispielsweise gibt der Operator + das Ergebnis der Addition zurück.
Nicht unbedingt:
#include <iostream>
struct foo {
int value = 0;
void operator+(int x) {
value += x;
}
};
int main () {
foo f;
f + 3;
}
Hier wird dem operator+
Element die linke Seite value
hinzugefügt, und sein Rückgabetyp ist ungültig. Dies ist ein erfundenes Beispiel, aber im Allgemeinen ist es nicht ungewöhnlich, etwas von einem benutzerdefinierten Operator nicht zurückzugeben.
Der einzige Operator, der überlastet werden kann und der die Anforderung hat, etwas zurückzugeben, das mir bekannt ist, ist operator->
. Es muss entweder einen Rohzeiger oder ein Objekt mit einem zurückgeben operator->
.
operator->
ist etwas Besonderes und muss entweder einen Zeiger oder ein Objekt zurückgeben, das eine hat operator->
, nicht sicher, ob es andere Ausnahmen gibt
operator*(Matrix const& left, Matrix const& right)
nicht, Matrix
sondern stattdessen zurückgegeben MatrixMul
wird. Wenn diese dann in operator+(Matrix const& left, MatrixMul const& right)
die Operation eingespeist wird, kann eine fusionierte Multiplikationsaddition erfolgen, die effizienter ist als zuerst zu multiplizieren und dann zu addieren.
<<
und >>
für E / A-Vorgänge überlastet sind, wird erwartet, dass sie den Stream zurückgeben, damit Sie sie kaskadieren können:stream << foo << bar;
Um nicht zu picken, geben die Operatoren nichts zurück. Sie sind nur lexikalische Elemente, mit denen wir Ausdrücke in der Sprache erstellen. Ausdrücke haben nun Typen und können zu Werten ausgewertet werden, und ich gehe davon aus, dass Sie dies unter Operatoren verstehen, die "Dinge zurückgeben".
Und ja. Es gibt C ++ - Ausdrücke vom Typ void
(und werden daher nicht zu einem Wert ausgewertet). Einige sind offensichtlich, andere weniger. Ein schönes Beispiel wäre
throw std::runtime_error()
throw
ist ein Ausdruck unter der C ++ - Grammatik. Sie können es in anderen Ausdrücken verwenden, beispielsweise im bedingten Ausdruck
return goodStatus() ? getValue() : throw std::runtime_error();
Und die Art eines Wurfausdrucks ist void
. Da dies nur dazu führt, dass die Ausführung schnell an eine andere Stelle geht, hat der Ausdruck offensichtlich keinen Wert.
Keiner der integrierten in C ++ Operatoren zurückkehren etwas. Überladene C ++ - Operatoren geben insofern etwas zurück, als die Operatornotation ein syntaktischer Zucker für einen Funktionsaufruf ist.
Vielmehr bewerten alle Bediener etwas. Das etwas hat einen genau definierten Wert sowie einen Typ . Auch der Funktionsaufrufoperator void operator()(/*params*/)
ist ein void
Typ.
Ist beispielsweise +'a'
ein int
Typ mit dem Wert " 'a'
Auf Ihrer Plattform codiert".
Wenn Ihre Frage lautet "Können C ++ - Operatoren einen void
Rückgabetyp haben?" dann lautet die Antwort mit Sicherheit ja.
I++
gibt keinen Wert zurück. Wenn der Typ von i
ein benutzerdefinierter Typ ist, wird dieser Ausdruck als implementiert operator++
. Dies ist eine Funktion, die einen Wert zurückgibt. Sie nennen das "syntaktischen Zucker"; Ich nenne das eine Unterscheidung, die wichtige Konsequenzen hat.
Sie können tatsächlich einen Funktionsaufrufoperator definieren , der nichts zurückgibt. Zum Beispiel:
struct Task {
void operator()() const;
};
Sie können die eigentümliche operator void()
Konvertierungsfunktion definieren , bei der der Compiler Sie sogar warnt, dass die T
to- void
Konvertierungsfunktion niemals verwendet wird :
#include <iostream>
struct Foo {
operator void() { std::cout << "Foo::operator void()!"; }
// warning: conversion function converting 'Foo' to
// 'void' will never be used
};
int main() {
Foo f;
(void)f; // nothing
f.operator void(); // Foo::operator void()!
}
gemäß [class.conv.fct] / 1
[...] Eine Konvertierungsfunktion wird niemals verwendet, um ein (möglicherweise cv-qualifiziertes) Objekt in den (möglicherweise cv-qualifizierten) gleichen Objekttyp (oder einen Verweis darauf) in eine (möglicherweise cv-qualifizierte) Basisklasse zu konvertieren dieses Typs (oder eines Verweises darauf) oder auf (möglicherweise cv-qualifiziert)
void
. 117( 117 ) Diese Konvertierungen werden als Standardkonvertierungen zum Zwecke der Überlastungsauflösung ([over.best.ics], [over.ics.ref]) und damit der Initialisierung ([dcl.init]) und expliziten Casts betrachtet. Eine Konvertierung nach
void
ruft keine Konvertierungsfunktion auf ([expr.static.cast]). Obwohl solche Konvertierungsfunktionen nie direkt aufgerufen wurden, um eine Konvertierung durchzuführen, können sie deklariert und möglicherweise durch einen Aufruf einer virtuellen Konvertierungsfunktion in einer Basisklasse erreicht werden.
Wie oben gezeigt, können Sie es dennoch mit der expliziten .operator void()
Syntax aufrufen .
Die durch die Sprache definierten (eingebauten) Operatoren sind Token, mit denen verschiedene Arten von Berechnungen durchgeführt werden:
und so weiter. Die Liste kann sehr umfangreich sein.
In Sprachreferenzen wie dieser oder jener wird nicht unbedingt darauf verwiesen, dass etwas zurückgegeben wird, sondern lediglich eine arithmetische oder logische Operation ausgeführt wird , ein Vergleich, durch den eine Variable geändert werden kann usw.
Da diese Operation zu einem bestimmten Wert führt, kann sie vom Operator als "zurückgegeben" interpretiert werden, unterscheidet sich jedoch von einem Funktionsrückgabewert.
Die überladenen Operatoren können andererseits mit einem Rückgabewert eines bestimmten Typs definiert werden, auch wenn dieser ungültig sein kann. Nein, nicht alle Operatoren geben einen Wert in C ++ zurück.
Ich gehe davon aus, dass Sie über Operatorfunktionen und nicht über Operatoren als syntaktische Einheit der Sprache sprechen.
Wenn Sie Operatoren für einen beliebigen Typ überladen, können Sie tatsächlich alles zurückgeben, was Sie möchten.
Dies ist auch sehr sinnvoll, da Operationen wie * oder () manchmal sehr intuitiv ihren Eingabetyp nicht zurückgeben. Stellen Sie sich vor, Sie multiplizieren einen komplexen Zahlentyp mit einem reellen Zahlentyp. Oder ein Operator, der ein Element aus einer Sammlung zurückgibt.
Sie können auch die Operatoren ++ und - überladen, um nichts zurückzugeben, wodurch die extrem fehleranfällige Mischung aus Nebeneffekt und Ausdruckswert in der Standardversion beseitigt wird.
Betrachten Sie diese beiden Beispiele hier:
int multiply (int a, int b) {
return a*b;
}
void multiply_void(int a, int b) {
cout << a*b;
//or cout << multiply(a,b);
}
Die erste Funktion gibt einen ganzzahligen Wert zurück, der von einer anderen Funktion verwendet werden kann. Der Wert wird zurückgegeben und im Speicher gespeichert, um bei Bedarf verwendet zu werden. Wenn nicht, ist es für den Menschen nicht sichtbar und sitzt einfach glücklich in der Erinnerung.
Die zweite Funktion wird auf dem Standardausgabegerät (normalerweise Konsole) ausgegeben. Der vom Multiplikationsoperator zurückgegebene Wert wird an ein Ausgabegerät übergeben. Die Funktion multiply_void gibt keinen tatsächlichen Wert zurück.
Die Betreiber selbst geben nicht unbedingt etwas zurück. Funktionsaufrufe geben Werte zurück. Operatoren können zu Werten führen. Bediener können manchmal Funktionen aufrufen. Beispiele beinhalten:
• Der Funktionsaufrufoperator.
• Ein überladener Operator, der in einen Funktionsaufruf umgewandelt wird.
• Der Operator new, der als Teil eines neuen Ausdrucks aufgerufen wird , ist ein Funktionsaufruf.
Mein einziger Zweck bei der Erwähnung von Funktionsaufrufen besteht darin, das Ergebnis im Vergleich zur Rückgabe zu klären. Basierend auf der Betrachtung aller 126 Instanzen von „return“ und der daraus abgeleiteten Wörter in [expr] scheint der Abschnitt das Wort return sorgfältig zu verwenden, um auf Folgendes zu verweisen:
• das Ergebnis eines Funktionsaufrufs
• Aspekte des Kontrollflusses in Bezug auf Coroutinen
OK, das ist genug Pedanterie für Ergebnis und Rückkehr.
C ++ - Operatoren geben etwas zurück oder nicht. Dies hängt davon ab, wie Sie sie verwendet haben. Integrierte C ++ - Operatoren geben einen Wert zurück, bis er erzwungen wird, void zurückzugeben.