c++ - ¿Por qué se llama al constructor de copia cuando se pasa temporalmente por referencia constante?
gcc pass-by-reference (3)
Estoy pasando un objeto temporal sin nombre a una función definida con el parámetro const ref. El ctor de copia de la clase es privado y recibo un error de compilación. No entiendo por qué se llama un constructor de copia en esta situación.
class A {
public:
A(int i) {}
private:
A(const A&) {}
};
void f(const A& a)
{
}
int main()
{
f(A(1)); // <-- error here: ''A::A(const A&)'' is private
}
Como era de esperar, cuando cambio la principal a:
A a(1);
f(a);
funciona.
EDITAR: el compilador es gcc 4.1.2
Debido a que a (1) llama al constructor A (int i) y luego se llama A (const A &) en la llamada a void f (const A &).
Haga que el constructor A (int i) sea explícito y no debería enfrentar este error.
Edit: creo que entendí mal la pregunta. Podría eliminar esto.
La expresión A(1)
es un rvalor 5.2.3 [expr.type.conv].
Al inicializar una referencia const
(el argumento de la función) con una expresión que es un rvalor, el compilador puede crear un temporal y copiar el valor de esa expresión al temporal y vincular esa referencia a ese temporal. 8.5.3 [dcl.init.ref] / 5.
[...] El constructor que se usaría para hacer la copia será llamable, ya sea que se haga o no la copia.
Tenga en cuenta que este comportamiento se debe cambiar en la próxima versión de C ++. En el nuevo estándar, una referencia const
inicializada desde un valor de clase debe vincularse directamente al objeto de referencia; en este caso no se permite crear un temporal y no se utiliza ni se requiere un constructor de copia.
Puede encontrar la respuesta a su pregunta en Copy Constructor Needed with temp object o ir directamente a http://gcc.gnu.org/bugs/#cxx%5Frvalbind
El estándar de C ++ dice que se debe crear un objeto temporal en este contexto y que su contenido debe rellenarse con una copia del objeto que estamos tratando de vincular a la referencia; También dice que la copia temporal puede ser eliminada, pero las restricciones semánticas (por ejemplo, accesibilidad) del constructor de la copia aún deben ser verificadas.
Para más información, puede consultar los siguientes párrafos del estándar de C ++: [dcl.init.ref] / 5, viñeta 2, subbala 1 y [class.temporary] / 2.
A partir de GCC 4.3.0, GCC ya no da un error para este caso. Este cambio se basa en la intención del comité de lenguaje C ++. A partir del 2010-05-28, el borrador final propuesto del estándar C ++ 0x permite este código sin errores.