2011-02-25 12 views
9

Es evidente que me falta algo importante sobre stringstreams en general aquí, pero podría alguien explicar por quéVolver stringstream de una función

#include <sstream> 
using namespace std; 

stringstream foo() { 
    stringstream ss; 
    return ss; 
} 

error con

In file included from /usr/include/c++/4.4/ios:39, 
      from /usr/include/c++/4.4/ostream:40, 
      from /usr/include/c++/4.4/iostream:40, 
      from rwalk.cpp:1:/usr/include/c++/4.4/bits/ios_base.h: In copy constructor ‘std::basic_ios<char, std::char_traits<char> >::basic_ios(const std::basic_ios<char, std::char_traits<char> >&)’:/usr/include/c++/4.4/bits/ios_base.h:790: error: ‘std::ios_base::ios_base(const std::ios_base&)’ is private 
/usr/include/c++/4.4/iosfwd:47: error: within this context 
/usr/include/c++/4.4/iosfwd: In copy constructor ‘std::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >::basic_stringstream(const std::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >&)’: 
/usr/include/c++/4.4/iosfwd:75: note: synthesized method ‘std::basic_ios<char, std::char_traits<char> >::basic_ios(const std::basic_ios<char, std::char_traits<char> >&)’ first required here 
/usr/include/c++/4.4/streambuf: In copy constructor ‘std::basic_stringbuf<char, std::char_traits<char>, std::allocator<char> >::basic_stringbuf(const std::basic_stringbuf<char, std::char_traits<char>, std::allocator<char> >&)’: 
/usr/include/c++/4.4/streambuf:770: error: ‘std::basic_streambuf<_CharT, _Traits>::basic_streambuf(const std::basic_streambuf<_CharT, _Traits>&) [with _CharT = char, _Traits = std::char_traits<char>]’ is private 
/usr/include/c++/4.4/iosfwd:63: error: within this context 
/usr/include/c++/4.4/iosfwd: In copy constructor ‘std::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >::basic_stringstream(const std::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >&)’: 
/usr/include/c++/4.4/iosfwd:75: note: synthesized method ‘std::basic_stringbuf<char, std::char_traits<char>, std::allocator<char> >::basic_stringbuf(const std::basic_stringbuf<char, std::char_traits<char>, std::allocator<char> >&)’ first required here 
rwalk.cpp: In function ‘std::stringstream foo()’: 
rwalk.cpp:12: note: synthesized method ‘std::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >::basic_stringstream(const std::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >&)’ first required here 

¿Cómo se puede volver un stringstream de una función ¿correctamente? (editar: agregó los encabezados para un fragmento de código completo y un error de escritura fijo)

Respuesta

19

Después de corregir el tipo-o en el tipo de devolución (indicado por Mahesh), su código no se compilará en C++ 03 porque stringstream no se puede copiar. Sin embargo, si su compilador es compatible con C++ 0x, activarlo le permite compilar su código porque stringstream es MoveConstructible.

+0

Creo que no se puede compilar incluso en C++ 11 sin 'std :: move()'. – magras

+0

@PetrPervukhin: ¿Por qué? De acuerdo con 27.8.6 [stringstream.cons], 'basic_stringstream' tiene un constructor de movimiento válido y accesible que se usará para mover' ss' fuera de 'foo'. ¿Hay alguna otra razón por la que ve que hace que el código no sea válido C++ 11? –

+0

Puedo decir acerca de C++ 03, que si no hay un constructor de copia en la clase A, no se puede escribir 'A a = A()', incluso si el compilador puede aplicar copy elction elision. Así que no estoy seguro de que el compilador pueda reemplazar la construcción de copias con la construcción de movimientos en este ejemplo. – magras

-2

Tiene que incluir sstream y tener std::stringstream en lugar de stringstream.

12

No se puede devolver un flujo de una función por valor, porque eso implica que tendría que copiar la secuencia. Las transmisiones en C++ no se pueden copiar.

+0

Gracias, yo no lo sabía. – Mahesh

+0

Puede que esté haciendo la pregunta incorrecta, pero ¿por qué no puedo copiar la transmisión? – Hooked

+5

@Hooked no es obvio cuál sería la semántica de las copias de secuencias. Cuando escribe en una copia, ¿la escritura también debe ocurrir en la otra? Cuando cierras una secuencia, ¿la otra se cierra también? Cuando cambia la configuración regional de una secuencia, ¿debería cambiar la otra también? En los programas correctos, no debe tener _need_ para copiar una secuencia. – wilhelmtell

2

En C++ 03 tendrá que pasar el stringstream como parámetro por referencia non-const o devolver solo la cadena resultante (ss.str()), ya que no puede copiar la secuencia.

3

Si bien no funciona en C++ 03, debería funcionar en C++ 11. Sin embargo, los compiladores actuales aún pueden tener problemas (debido a la falta de compatibilidad completa de C++ 11), p. el código anterior no se compilará en g ++ 4.6.1

1

Pregunta anterior, pero creo que la forma correcta de lograr lo que desea es usar el método stringstream::str que devuelve un objeto de cadena con una copia de los contenidos actuales en la secuencia buffer.

Aquí hay un ejemplo con string str() const;.

std::string foo() { 
    stringstream ss; 
    ss << "add whatever you want to the stream" << 12 << ' ' << 13.4; 
    return ss.str(); 
} 

int main() { 
    std::cout << foo(); 
    return 0; 
} 

que imprime:

add whatever you want to the stream 12 13.4 
Cuestiones relacionadas