2010-07-12 3 views
7

È possibile sovraccaricare una funzione che accetta un nome di riferimento o una variabile?Problema con il passaggio tramite riferimento

Per esempio quando cerco di fare questo:

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

Vorrei che il chiamante di questa funzione per essere in grado di fare:

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

vorrei scrivere pass-by- funzioni di riferimento per un migliore utilizzo della memoria e la possibile manipolazione della variabile al di fuori dell'ambito, ma senza dover creare una nuova variabile solo per poter chiamare la funzione.

È possibile?

Acclamazioni

+1

Penso che questo sia generalmente possibile, anche se nel tuo esempio, entrambi chiameranno 'function (double a)', poiché un è un int e non può essere preso come riferimento a un doppio. – falstro

+0

mi dispiace per quello, intendevo dire che è un doppio. Corretto in questione ora –

+0

Cosa intendi per "possibile manipolazione della variabile al di fuori dell'ambito", e come funzionerebbe con 'function (2.3)' – Roddy

risposta

8

Penso che manchi il punto qui. Quello che dovresti davvero è solo questo:

void function(const double &a); 

Nota "const". Con quello, dovresti sempre ottenere un riferimento pass-by. Se hai un passaggio non const per riferimento, il compilatore supporrà correttamente che desideri modificare l'oggetto passato, che ovviamente è concettualmente incompatibile con la variante pass-by-value.

Con i riferimenti const, il compilatore creerà felicemente l'oggetto temporaneo per te dietro la schiena. La versione non const non funziona per te, perché il compilatore può solo creare questi oggetti temporanei come oggetti "const".

+0

CAVEAT: Se "function" non può essere inline, quindi "const double &" potrebbe essere più costoso perché forza "a" in memoria. La maggior parte dei compilatori passerà il doppio nei registri se la loro modalità argomento è in valore. –

+2

Infatti. La convenzione in C++ di solito passa per tipi predefiniti (int, double, char, puntatori, ecc.) Per valore, e tipi compositi (classi e struct) per riferimento. –

+0

@Tyler, Luther. Ovviamente siete entrambi corretti. Suppongo che la scelta del 'doppio' sia solo un tipo scelto come esempio (leggermente scarso) ... – Roddy

0

non credo che la definizione:

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

è possibile ... Come sarebbe il compilatore sapere quale funzione da chiamare per function(x)? Se si desidera utilizzare sia per riferimento che per valore, è necessario utilizzare due diverse funzioni. Questo renderebbe anche il codice molto più facile da leggere rispetto a questo ambiguo sovraccarico.

+0

Penso che sia possibile, e la versione di riferimento sarà preferibile se possibile . Non ho nulla per sostenere quella richiesta però. – falstro

+0

Indovina provo con diversi compilatori ... – Tapdingo

+0

gcc 4.1.2: errore: chiamata di overloaded 'function (int &)' è ambigua – Tapdingo

1

ho provato, ed è fallito

Almeno in MSVC2008, questo non è possibile - e credo che questo applys a tutti C++ - compilatori.

Il definiton stessa è valida, ma quando si cerca di chiamare la funzione

function(a); 

con una variabile come parametro, un errore di compilatore viene sollevato come il compilatore è in grado di decidere quale funzione utilizzare.

-1

No, non è possibile eseguire questo coz entrambe le funzioni produrranno effettivamente gli stessi nomi storti e il linker non sarebbe in grado di risolvere la chiamata di funzione.

+0

Uhm. No. Un parametro di riferimento non produrrà lo stesso nome di un normale (parametro copiato). Ciò equivarrebbe a dire che un parametro pointer-to-double e un parametro double darebbero entrambi lo stesso nome di mangling. – falstro

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

Non c'è alcun vantaggio di passare i tipi POD per riferimento, poiché sono quasi sempre (sempre?) Passati in un registro. I tipi complessi (quelli che consistono in più di una sola variabile POD) passati da riferimento const sono usuali (sempre? D) un modo preferibile su una copia e uno stack. Puoi persino controllare la creazione di temporanee delle tue variabili complesse dai tipi POD creando explicit constructors