tipo referencia que por pasar parametros parametro objetos funciones entrada como argumentos c++ gcc reference

c++ - que - tipo por referencia c#



¿Cuándo no se puede convertir un objeto a una referencia? (2)

Deseo compilar la siguiente línea de código de http://code.google.com/p/enhsim :

enh::eout << enh::setw(26);

gcc da el siguiente error:

error: no match for ''operator<<'' in ''enh::eout << enh::setw(26)''

Pero la clase EnhSimOutput (de la cual enh::eout es una instancia) declara:

EnhSimOutput& operator<< (setw& p);

Este problema desaparece si implemento una versión de la operación que acepta el objeto por valor:

EnhSimOutput& operator<< (setw p);

o si creo el objeto enh::setw como local, es decir:

enh::setw wValue(26); enh::eout << wValue;

Mi pregunta es esta: ¿por qué gcc no selecciona la versión "por referencia" del operador para empezar?

Los desarrolladores que escribieron este código claramente lo compilaron, pero el gcc predeterminado se rehúsa a hacerlo. ¿Por qué hay una diferencia entre un objeto declarado por separado como una variable local y un local creado en línea?


Mi suposición es que EnhSimOutput& operator<< (setw& p); pasa por referencia no constante, pero el valor 26 es "const" en el sentido de que no se puede modificar. Intente configurarlo en EnhSimOutput& operator<< (const setw& p);

o tratar

int nNumber = 26; enh::eout << enh::setw(nNumber);


El valor enh::setw(26); es un rvalue En realidad, los temporales así son valores. Los valores R tienen propiedades especiales. Una de ellas es que su dirección no puede tomarse ( &enh::setw(26); es ilegal), y generalmente no pueden vincularse a referencias a no-const (algunos temporales pueden enlazarse a referencias a no-const, pero estos se someten a reglas especiales: Llamar a funciones miembro sobre objetos temporales y atrapar objetos de excepción por referencia a no-const. En este último caso, el valor par temporal es un valor l ).

Hay dos tipos de expresiones: lvalues que denotan objetos (que a su vez pueden almacenar un valor) o funciones, y rvalues que deben representar valores leídos de un objeto o representados por temporarios, literales numerales y constantes del enumerador. En C ++ 03, para poder pasar dichos valores a una función que acepta su valor por referencia, existe una regla de que pueden ser aceptados por referencia-a-const: setw const& p lo aceptará. Es decir, tendrías que declarar a tu operador así:

EnhSimOutput& operator<< (setw const& p);

Eso es un poco desafortunado, porque no puedes eliminar la ambigüedad de los valores l constantes (objetos que creaste en la pila usando const enh::setw e(26); por ejemplo) y enh::setw(26); no const o const (como enh::setw(26); que es un temporal no const). Además, si lo hace, el parámetro no puede haber llamado a funciones de miembros no const, porque es una referencia-a-const. Por esa razón, C ++ 1x, la próxima versión de C ++, introduce un nuevo tipo de referencia, las denominadas referencias-rvalue que corrige eso.

El compilador de Microsoft Visual C ++ vincula valores a las referencias a no const, pero emite una advertencia al hacerlo (debe usar al menos el nivel de advertencia 4 para que se muestre). Eso es desafortunado, porque los problemas aumentan cuando se transfiere a otros compiladores que son más estrictos en el cumplimiento de estándares.