Question

Considérez ce code,

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);
}

compiles bien, fonctionne très bien. Mais si je change f(B) à f(B&), il ne compile pas . Si je vous écris f(const B&), encore compile bien , fonctionne très bien. Pourquoi la raison et la raison?

Résumé:

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

Je voudrais entendre raisons, justification et référence (s) de la spécification du langage, pour chacun de ces cas. Bien sûr, les signatures de fonction ne sont pas elles-mêmes incorrectes. Au contraire A implicitement convertis en B et const B&, mais pas en B&, et qui provoque l'erreur de compilation.

Était-ce utile?

La solution

  

Je voudrais entendre raisons, justification et référence (s) de la spécification du langage

est La conception et l'évolution de C ++ suffisant?

  

J'ai fait une grave erreur, mais, en permettant une référence non-const à initialiser par un non-lvalue [ Commentaire de moi: ce libellé est imprécis !]. Par exemple:

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

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

En raison de la différence dans le type de la int& ne peut pas se référer à la double passé si temporaire a été généré pour tenir un int initialisé par la valeur de ss. Ainsi, incr() modifié le temporaire, et le résultat n'a pas été réfléchie à la fonction appelant [ Souligné par l'auteur ].

Pensez-y: Le point entier de l'appel par référence est que le client passe des choses qui sont modifiées par la fonction, et après le retour de la fonction, le client doit être en mesure d'observer les changements .

Autres conseils

Le problème est que la conversion implicite à partir d'un à un objet B donne un rvalue. Les références non const ne peuvent se lier à lvalues.

Si B avait un constructeur par défaut, vous obtiendrez le même comportement si vous changez l'appel f(a) à f(B()).

-

litb fournit une excellente réponse à ce qui est une lvalue: Stack Overflow - souvent utilisé des termes rarement définis: lvalue

GotW # 88: un candidat pour le « plus important const »

Stack Overflow - Comment venir ne peut pas se lier à une référence non-const à un objet temporaire?

-

Pour expliquer avec des références à la norme la façon dont ces appels de fonctions échouent ou réussissent serait trop long. L'important est de savoir comment B& b = a; échoue alors que const B& b = a; ne manque pas.

(du projet n1905)

  

La mention de type « CV1 T1 » est initialisé par une expression de type « T2 CV2 » comme suit:
    - [ est une lvalue et est soit référence compatible ou implicitement convertible en une lvalue d'un type compatible de référence ... ]
    -. Dans le cas contraire, la référence est à un type de const non-volatile (par exemple, CV1 est const)

est un cas où quelque chose est convertible à un lvalue de référence type compatible.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top