La conversión implícita: referencia const vs referencia no const vs no es de referencia
-
11-10-2019 - |
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.
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 ladouble
pasaron por lo que un temporal se generó a cabo unaint
inicializado por el valor dess
. 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”
-
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.