2010-07-12 5 views
7

Kann ich eine Funktion überladen, die entweder einen Referenz- oder Variablennamen verwendet?Problem mit der Weitergabe durch Referenz

Zum Beispiel, wenn ich versuche, dies zu tun:

void function(double a); 
void function(double &a); 

ich den Aufrufer dieser Funktion zu tun in der Lage sein möchte:

double a = 2.5; 
function(a); // should call function(double &a) 
function(2.3); // should call function(double a) 

Ich möchte Pass-by- schreiben Referenzfunktionen für eine bessere Speichernutzung und eine mögliche Manipulation der Variablen außerhalb des Bereichs, aber ohne eine neue Variable erstellen zu müssen, damit ich die Funktion aufrufen kann.

Ist das möglich?

Prost

+1

erstellen. Ich denke, das ist generell möglich, obwohl in Ihrem Beispiel beide 'function (double a)' aufrufen, da a ist ein Int und kann nicht als ein Verweis auf ein Double genommen werden. – falstro

+0

Entschuldigung, das bedeutet, dass ein Doppelgänger ist. Korrigiert in Frage –

+0

Was meinst du mit "mögliche Manipulation der Variablen außerhalb des Geltungsbereichs", und wie würde das funktionieren mit 'Funktion (2.3)' – Roddy

Antwort

8

Ich denke, du verpasst den Punkt hier. Was Sie wirklich haben sollten, ist gerade dies:

void function(const double &a); 

Beachten Sie die "const". Damit sollten Sie immer Pass-by-Reference erhalten. Wenn Sie nicht-const als Verweis übergeben haben, wird der Compiler korrekt davon ausgehen, dass Sie das übergebene Objekt ändern möchten - was natürlich konzeptuell mit der Pass-by-Value-Variante inkompatibel ist.

Mit Const-Referenzen erstellt der Compiler glücklich das temporäre Objekt für Sie hinter Ihrem Rücken. Die nicht-const-Version funktioniert nicht für Sie, da der Compiler diese Provisorien nur als "const" -Objekte erstellen kann.

+0

CAVEAT: Wenn "Funktion" nicht inline sein kann, dann kann "const double &" teurer sein, weil es "a" in den Speicher zwingt. Die meisten Compiler werden Doppelbelegungen in Registern übergeben, wenn ihr Argumentmodus dem Wert entspricht. –

+2

In der Tat. Die Konvention in C++ besteht normalerweise darin, integrierte Typen (int, double, char, pointer usw.) nach Wert und zusammengesetzte Typen (Klassen und Strukturen) als Referenz zu übergeben. –

+0

@Tyler, Luther. Sie sind natürlich beide richtig. Ich gehe davon aus, dass die Wahl von "double" nur ein Typ ist, der als (etwas armes) Beispiel gewählt wurde ... – Roddy

0

Ich glaube nicht die Definition:

void function(double a); 
void function(double &a); 

ist möglich ... Wie würde der Compiler wissen, welche Funktion für function(x) anrufen? Wenn Sie sowohl nach Referenz als auch nach Wert verwenden möchten, sollten Sie zwei verschiedene Funktionen verwenden. Dies würde auch den Code viel einfacher zu lesen, als diese mehrdeutige Überladung.

+0

Ich denke, es ist möglich, und die Referenz-Version wird bevorzugt, wenn möglich . Habe aber nichts, um diesen Anspruch zu untermauern. – falstro

+0

Rate mal, ich werde es mit verschiedenen Compilern ausprobieren ... – Tapdingo

+0

gcc 4.1.2: error: Aufruf der überladenen 'Funktion (int &)' ist mehrdeutig – Tapdingo

1

ich es versucht, und es scheiterte

MINDESTENS in MSVC2008, ist dies nicht möglich ist - und ich denke, dies für alle c applys ++ - Compiler.

Die Definiton selbst ist gültig, aber beim Versuch, die Funktion

function(a); 

mit einer Variablen als Parameter zu nennen, ein Compiler-Fehler ausgelöst wird, wie der Compiler nicht in der Lage ist, zu entscheiden, welche zu verwenden, funktionieren.

-1

Nein, Sie können dies nicht tun, da beide Funktionen effektiv die gleichen verfälschten Namen erzeugen und der Linker den Funktionsaufruf nicht auflösen kann.

+0

Uhm. Nein. Ein Referenzparameter erzeugt nicht denselben Namen wie ein normaler (kopierter Parameter). Das wäre äquivalent zu sagen, dass ein Pointer-zu-Doppel- und ein Doppel-Parameter beide den gleichen Namen Mangling ergeben würden. – falstro

1
void function(double const &a); // instead of void function(double a); 
void function(double  &a); 
0

Es gibt keinen Vorteil POD-Typen als Referenz zu übergeben, da sie fast immer (immer?) In einer Registry übergeben werden. Komplexe Typen (die aus mehr als nur einer POD-Variablen bestehen), die von const referenz übergeben werden, sind normalerweise (immer?: D) eine vorzuziehende Methode über einen Kopier- und Stapel-Push. Sie können sogar die Erstellung von Provisorien Ihrer komplexen typisierten Variablen aus POD-Typen steuern, indem Sie explicit constructors