Domanda

Si consideri questo codice,

struct A {};
struct B {  B(const A&) {} };
void f(B)
{
    cout << "f()"<<endl;
}
void g(A &a)
{
    cout << "g()" <<endl;
    f(a); //a is implicitly converted into B.
}
int main()
{
    A a;
    g(a);
}

compila bene , funziona benissimo. Ma se cambio f(B) a f(B&), è non viene compilato . Se scrivo f(const B&), di nuovo compila bene , funziona benissimo. Perché è la ragione e la logica?

Sommario:

void f(B);         //okay
void f(B&);        //error
void f(const B&);  //okay

Mi piacerebbe sentire ragioni, delle motivazioni e riferimento (s) dal specifica del linguaggio, per ciascuno di questi casi. Naturalmente, le firme di funzione stessi non sono corretti. Piuttosto A implicitamente si trasforma in B e const B&, ma non in B&, e che causa l'errore di compilazione.

È stato utile?

Soluzione

Mi piacerebbe sentire ragioni, delle motivazioni e riferimento (s) dal specifica del linguaggio

Il design e l'evoluzione del C ++ è sufficiente?

ho fatto un grave errore, però, consentendo un riferimento non const da inizializzare da un non lvalue [ commento di me: tale formulazione è imprecisa !]. Ad esempio:

void incr(int& rr) { ++rr; }

void g()
{
    double ss = 1;
    incr(ss);    // note: double passed, int expected
                 // (fixed: error in release 2.0)
}

A causa della differenza nel tipo il int& non può fare riferimento al passato double modo temporaneo è stato generato per contenere un int inizializzato al valore di ss. Così, incr() modificato il temporanea, e il risultato non si è riflessa indietro alla funzione di chiamata [ sottolineatura mia ].

Pensateci: Il punto di chiamata per riferimento è che il client passa le cose che vengono modificate dalla funzione, e dopo la funzione ritorna, il cliente deve essere in grado di osservare i cambiamenti .

Altri suggerimenti

Il problema è che la conversione implicita da una a un oggetto B produce una rvalue. riferimenti non-const possono legarsi solo per lvalue.

Se B ha avuto un costruttore di default si otterrebbe lo stesso comportamento se si cambia la chiamata f(a) a f(B()).

-

litb fornisce una grande risposta a ciò che è un lvalue: Stack Overflow - spesso utilizzati termini raramente definiti: lvalue

GotW # 88: un candidato per il “Most const importante”

Stack Overflow - Come mai un riferimento non-const non può legarsi ad un oggetto temporaneo?

-

Per spiegare con riferimenti alla norma come quei chiamate di funzione o non riescono ad avere successo sarebbe eccessivamente lungo. La cosa importante è come B& b = a; fallisce mentre const B& b = a; non fallisce.

(da progetto n1905)

Un riferimento a tipo “CV1 T1” viene inizializzato da un'espressione di tipo “cv2 T2” come segue:
- [ è un lvalue ed è uno di riferimento compatibile o implicitamente convertibile in un lvalue di un tipo compatibile di riferimento ... ]
-. In caso contrario, il riferimento deve essere di tipo const non volatile (cioè, CV1 è const)

Ecco un caso in cui qualcosa è convertibile ad un lvalue di tipo compatibile di riferimento.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top