Pregunta

Considere este código,

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 bien , funciona muy bien. Pero si cambio f(B) a f(B&), que no compila . Si escribo f(const B&), de nuevo compila bien , funciona muy bien. ¿Por qué es el motivo y razón de ser?

Resumen:

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

Me gustaría escuchar razones, fundamentos y referencia (s) a partir de la especificación del lenguaje, para cada uno de estos casos. Por supuesto, las firmas de función en sí no son correctos. En lugar A implícitamente convertidos en B y const B&, pero no en B&, y que hace que el error de compilación.

¿Fue útil?

Solución

Me gustaría escuchar razones, fundamentos y referencia (s) a partir de la especificación del lenguaje

Es El Diseño y Evolución de C ++ suficiente?

Me hizo un grave error, sin embargo, al permitir que una referencia no const a ser inicializado por un no-valor-I [ Comentario por mí: que la redacción es imprecisa !]. Por ejemplo:

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

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

Debido a la diferencia en el tipo del int& no puede referirse a la double pasaron por lo que un temporal se generó a cabo una int inicializado por el valor de ss. Por lo tanto, incr() modificó el temporal, y el resultado no se reflejó de nuevo a la función de llamada [ énfasis mío ].

Piense en esto: El punto de llamada por referencia es que el cliente pasa a las cosas que son modificados por la función, y después de la función regresa, el cliente debe ser capaz de observar los cambios .

Otros consejos

El problema es que la conversión implícita de un a un objeto B se obtiene un valor p. referencias no const sólo pueden unirse a lvalues.

Si B tenía un constructor por defecto que se obtendría el mismo comportamiento si cambia la llamada a f(a) f(B()).

-

litb proporciona una gran respuesta a lo que es un valor-i: desbordamiento de pila - rara vez definidos los términos de uso frecuente: lvalue

GotW # 88: Un candidato para el “const más importante”

desbordamiento de pila - ¿Cómo es que una referencia no const no se puede enlazar a un objeto temporal?

-

Para explicar con referencia a la norma de cómo esas llamadas de función fracasan o tienen éxito sería excesivamente largo. Lo importante es cómo B& b = a; falla mientras const B& b = a; no falla.

(de proyecto n1905)

Una referencia a escribir “CV1 T1” se inicializa por una expresión de tipo “cv2 T2” como sigue:
- [ es un valor-I y de que sea compatible o referencia convertir implícitamente a un valor izquierdo de un tipo compatible referencia ... ]
-. De lo contrario, la referencia será a un tipo const no volátil (es decir, CV1 será const)

Aquí es un caso en el que algo se puede convertir en un valor-i de referencia de tipo compatible.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top