§27.7.3.9
define los siguientes sobrecarga para operator<<
:¿Por qué la sobrevalor r de `operator <<` for `basic_ostream` devuelve una referencia lvalue?
template <class charT, class traits, class T>
basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>&& os, const T& x);
Efectos:
os << x
Devuelve:os
(§27.7.2.6
define la sobrecarga rvalue para operator>>
.)
Básicamente, simplemente reenvía a una sobrecarga lvalue. Considero que esta sobrecarga a ser bastante peligroso (el istream
uno incluso más que el ostream
uno, en realidad), tenga en cuenta lo siguiente:
#include <sstream>
#include <iostream>
int main(){
auto& s = (std::stringstream() << "hi there!\n");
std::cout << s.rdbuf(); // oops
}
Live example on Ideone (perfecto ejemplo de un comportamiento indefinido imprime nada para mí en MSVC10.).
El ejemplo anterior puede parecer artificial, pero no debe ser demasiado difícil llegar a esta situación en el código genérico o al pasar el (std::stringstream() << "text")
a una función que proporciona un valor izquierdo y una sobrecarga rvalue y almacena el std::ostream
o en std::istream
diferentes formas según la sobrecarga.
Ahora, ¿cuál sería un argumento en contra de devolver un basic_ostream<charT, traits>&&
y especificar lo siguiente?
Devuelve: (. Y lo mismo para
basic_istream
) movimiento (os)
¿Hay algo que estoy pasando por alto? En el estado actual, en mi opinión, parece peligroso y como un defecto. Revisé el LWG issue list y encontré this proposal (hi @HowardHinnant!). De hecho, devuelve un valor r, sin embargo, solo por el beneficio adicional de poder encadenar a este operador especial, no abordando específicamente el problema de seguridad que describí anteriormente (aunque ciertamente lo resuelve). Además, está marcado como cerrado y para reconsideración para el próximo estándar. Como tal, pensé en preguntar aquí:
¿Hay alguna buena razón por la sobrecarga antes mencionada devuelve una referencia lvalue?
por alguna razón, todos los MSVC que he visto parecen permitir que uno enlace valores a una referencia no constante, por lo que devolver el valor de rvalue no cambiará nada para MSVS. –