Primo motivo: std::ostream
s non sono copiabili in generale (in C++ 11 il costruttore di copie è in realtà delete
d). Se non si desidera restituire una copia comunque perché il concatenamento non avrebbe funzionato:
std::stringstream s;
s << "String1" << "String2";
sarebbe riuscire a compilare perché perché la copia restituito dalla prima chiamata operatore non sarebbe convertibile al riferimento richiesto per la seconda chiamata .
Rendere entrambi i valori, invece di riferimenti, inoltre, non avrebbe funzionato:
std::stringstream s;
s << "String1" << "String2";
assert(s.str() == "String1String2");
il codice verrà compilato, ma l'asserzione non riuscirà perché l'oggetto s
rimane invariato dopo queste chiamate perché è stato superato da copia anziché per riferimento.
Seconda ragione: tutti gli oggetti effettivi stream
da utilizzare derivano da std::ostream
. Se questo parametro è passato per copia, ottieni slicing in cui perdi effettivamente l'oggetto che stavi utilizzando.
Questo significa che il seguente codice non funzionerebbe (se il passaggio per riferimento ma tornando da copy-e in qualche modo andare in giro l'errore di compilazione?):
std::stringstream s;
s << "String1" << "String2" << std::endl;
assert(s == "String1String2");
s
terrebbe solo "String1"
in questo caso perché quando sei tornato il std::stringstream
per copia di std::ostream
, l'oggetto restituito non è più un oggetto std::stringstream
e chiama operator<<
su quello passa "String2"
in un oggetto temporaneo che viene appena distrutto alla fine.
Queste sono le due ragioni importanti a cui posso pensare di tornare per riferimento e non per valore.