Algunos operadores devuelven valor, algunos por referencia. En general, un operador cuyo resultado es un nuevo valor (como +, -, etc.) debe devolver el nuevo valor por valor, y un operador cuyo resultado es un valor existente, pero modificado (como < <, >>, + =, - =, etc.), debe devolver una referencia al valor modificado.
Por ejemplo, cout
es una std::ostream
, y la inserción de datos en la corriente es una operación de modificación, por lo que para implementar el operador <<
para insertar en un ostream
, el operador se define así:
std::ostream& operator<< (std::ostream& lhs, const MyType& rhs)
{
// Do whatever to put the contents of the rhs object into the lhs stream
return lhs;
}
Este De esta manera, cuando tiene una declaración compuesta como cout << x << y
, primero se evalúa la sub-expresión cout << x
y luego se evalúa la expresión [result of cout << x ] << y
. Dado que el operador <<
en x
devuelve una referencia a cout
, la expresión [result of cout << x ] << y
es equivalente a cout << y
, como se esperaba.
Por el contrario, para "string + string", el resultado es una nueva cadena (ambas cadenas originales no se modifican), por lo que debe devolver por valor (de lo contrario, devolvería una referencia a un comportamiento temporal, indefinido) .
Lo que va de la mano con "si es const, devuelve un valor, si no es const, devuelve una referencia". – GManNickG
Técnicamente '<<' no modifica el valor existente. Es solo un operador de cambio a la izquierda. Es la interfaz de transmisión que rompe las reglas. – kennytm
@GMan correcto, aunque eso no cubre los casos (como 'operator <<') donde la sobrecarga se implementa como no miembro. –