Ist es möglich, einem Parameter einer Funktion einen Standardwert zuzuweisen, während wir den Parameter als Referenz übergeben? in C ++
Zum Beispiel, wenn ich versuche, eine Funktion wie folgt zu deklarieren:
virtual const ULONG Write(ULONG &State = 0, bool sequence = true);
Wenn ich das mache, gibt es einen Fehler:
Fehler C2440: 'Standardargument': Konvertiert nicht von 'const int' in 'unsigned long &' Ein Verweis, der nicht auf 'const' lautet, kann nicht an einen Nicht-l-Wert gebunden werden
c++
pass-by-reference
default-value
Drew Noakes
quelle
quelle
WxWidgets style guide says "don't use templates" and they have good reasons
<- Schraube std :: vector, ich sageAntworten:
Sie können dies für eine konstante Referenz tun, jedoch nicht für eine nicht konstante. Dies liegt daran, dass C ++ nicht zulässt, dass ein temporärer Wert (in diesem Fall der Standardwert) an eine nicht konstante Referenz gebunden wird.
Eine Möglichkeit, dies zu umgehen, besteht darin, eine tatsächliche Instanz als Standard zu verwenden:
Dies ist jedoch von sehr begrenztem praktischem Nutzen.
quelle
Es wurde bereits in einem der direkten Kommentare zu Ihrer Antwort gesagt, aber nur um es offiziell zu erklären. Was Sie verwenden möchten, ist eine Überlastung:
Die Verwendung von Funktionsüberladungen bietet zusätzliche Vorteile. Erstens können Sie jedes gewünschte Argument als Standard festlegen:
Es ist auch möglich, Standardargumente für virtuelle Funktionen in abgeleiteten Klassen neu zu definieren, wodurch eine Überladung vermieden wird:
Es gibt nur eine Situation, in der ein Standardwert wirklich verwendet werden muss, und zwar auf einem Konstruktor. Es ist nicht möglich, einen Konstruktor von einem anderen aufzurufen, daher funktioniert diese Technik in diesem Fall nicht.
quelle
d.f2(); // f2(int) called with '0' b.f2(); // f2(int) called with '0'
Es gibt immer noch die alte C-Methode, optionale Argumente bereitzustellen: Ein Zeiger, der NULL sein kann, wenn er nicht vorhanden ist:
quelle
Diese kleine Vorlage hilft Ihnen:
Dann können Sie:
quelle
ByRef
die Erinnerung? Ist es nicht ein temporäres Objekt, das beim Verlassen eines Bereichs zerstört wird (wie der Konstruktor)?Nein, es ist nicht möglich.
Das Übergeben als Referenz impliziert, dass die Funktion den Wert des Parameters ändern kann. Wenn der Parameter nicht vom Aufrufer bereitgestellt wird und von der Standardkonstante stammt, welche Funktion soll sich ändern?
quelle
Es gibt zwei Gründe, ein Argument als Referenz zu übergeben: (1) für die Leistung (in diesem Fall möchten Sie als Konstantenreferenz übergeben) und (2), weil Sie die Fähigkeit benötigen, den Wert des Arguments innerhalb der Funktion zu ändern.
Ich bezweifle sehr, dass das Übergeben eines unsignierten Longs für moderne Architekturen Sie zu sehr verlangsamt. Ich gehe also davon aus, dass Sie beabsichtigen, den Wert
State
innerhalb der Methode zu ändern . Der Compiler beschwert sich, weil die Konstante0
nicht geändert werden kann, da es sich um einen r-Wert ("nicht-l-Wert" in der Fehlermeldung) und einen unveränderlichen Wert handelt (const
in der Fehlermeldung) ist.Einfach ausgedrückt, Sie möchten eine Methode, die das übergebene Argument ändern kann, aber standardmäßig möchten Sie ein Argument übergeben, das sich nicht ändern kann.
Anders ausgedrückt, Nichtreferenzen
const
müssen sich auf tatsächliche Variablen beziehen. Der Standardwert in der Funktionssignatur (0
) ist keine echte Variable. Sie haben das gleiche Problem wie:Wenn Sie nicht beabsichtigen,
State
die Methode zu ändern , können Sie sie einfach in a ändernconst ULONG&
. Aber Sie werden keinen großen Leistungsvorteil davon erhalten, daher würde ich empfehlen, es in eine Nichtreferenz zu ändernULONG
. Ich stelle fest, dass Sie a bereits zurückgebenULONG
, und ich habe den Verdacht, dass sein Wert der WertState
nach erforderlichen Änderungen ist. In diesem Fall würde ich die Methode einfach so deklarieren:Natürlich bin ich mir nicht ganz sicher, was Sie schreiben oder wohin. Aber das ist eine andere Frage für eine andere Zeit.
quelle
Sie können kein konstantes Literal für einen Standardparameter verwenden, aus demselben Grund, aus dem Sie keines als Parameter für den Funktionsaufruf verwenden können. Referenzwerte müssen eine Adresse haben, konstante Referenzwerte müssen keine Adresse haben (dh sie können r-Werte oder konstante Literale sein).
Stellen Sie sicher, dass Ihr Standardwert eine Adresse hat und es Ihnen gut geht.
Ich habe dieses Muster einige Male verwendet, als ich einen Parameter hatte, der eine Variable oder Null sein konnte. Der reguläre Ansatz besteht darin, dass der Benutzer einen Zeiger übergibt. Dies ist der Fall. Sie übergeben einen NULL-Zeiger, wenn Sie den Wert nicht eingeben sollen. Ich mag es, den Objektansatz auf Null zu setzen. Dies erleichtert dem Anrufer das Leben, ohne den Angerufenencode zu erschweren.
quelle
Ich denke nicht, und der Grund dafür ist, dass Standardwerte als Konstanten ausgewertet werden und Werte, die als Referenz übergeben werden, sich ändern können müssen, es sei denn, Sie deklarieren sie auch als konstante Referenz.
quelle
Ein anderer Weg könnte der folgende sein:
dann sind folgende aufrufe möglich:
quelle
quelle
Im Fall von OO ... Zu sagen, dass eine bestimmte Klasse hat und "Standard" bedeutet, dass dieser Standard (Wert) entsprechend deklariert werden muss und dann als Standardparameter verwendet werden kann, z.
Auf Ihrer Methode ...
Diese Lösung ist sehr gut geeignet, da in diesem Fall "Globale Standardpaginierung" ein einzelner "Referenzwert" ist. Sie haben auch die Möglichkeit, Standardwerte zur Laufzeit zu ändern, z. B. eine Konfiguration auf "globaler Ebene", z. B.: Navigationseinstellungen für die Benutzer-Paginierung usw.
quelle
Es ist möglich mit const Qualifier für State:
quelle
quelle
Dafür gibt es auch einen ziemlich schmutzigen Trick:
In diesem Fall müssen Sie es aufrufen mit
std::move
:Es ist nur eine lustige Problemumgehung, ich empfehle die Verwendung in echtem Code überhaupt nicht!
quelle
Ich habe eine Problemumgehung dafür, siehe das folgende Beispiel zum Standardwert für
int&
:Sie können es für jeden trivialen Datentyp Sie wünschen, wie
bool
,double
...quelle
Die Antwort ist recht einfach und ich kann nicht so gut erklären, aber wenn Sie einen Standardwert an einen nicht konstanten Parameter übergeben möchten, der wahrscheinlich in dieser Funktion geändert wird, verwenden Sie ihn wie folgt:
quelle