2012-03-27 17 views
5

Esta es una pregunta simple y compleja al mismo tiempo.cargando fstreams en un std :: vector en C++

Esto compila:

int Test; 
vector<int> TEST; 
TEST.push_back(Test); 
cout << TEST.size(); 

Esto no se compila:

fstream Test; 
vector<fstream> TEST; 
TEST.push_back(Test); 
cout << TEST.size(); 

¿Hay alguna razón en particular? ¿Hay alguna manera de obtener una lista dinámica de flujos?

El mensaje de error:

1>------ Build started: Project: vector_test, Configuration: Debug Win32 ------ 
1> vector_test.cpp 
1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\fstream(1347): error C2248: 'std::basic_ios<_Elem,_Traits>::basic_ios' : cannot access private member declared in class 'std::basic_ios<_Elem,_Traits>' 
1>   with 
1>   [ 
1>    _Elem=char, 
1>    _Traits=std::char_traits<char> 
1>   ] 
1>   c:\program files (x86)\microsoft visual studio 10.0\vc\include\ios(176) : see declaration of 'std::basic_ios<_Elem,_Traits>::basic_ios' 
1>   with 
1>   [ 
1>    _Elem=char, 
1>    _Traits=std::char_traits<char> 
1>   ] 
1>   This diagnostic occurred in the compiler generated function 'std::basic_fstream<_Elem,_Traits>::basic_fstream(const std::basic_fstream<_Elem,_Traits> &)' 
1>   with 
1>   [ 
1>    _Elem=char, 
1>    _Traits=std::char_traits<char> 
1>   ] 
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ========== 
+0

En C++, esto será posible: IOStreams son móviles, y el vector admitirá tipos móviles. – MSalters

+0

@MSalters: una referencia a la parte del estándar C++ 11 que indica lo anterior podría ser útil ;-) –

+1

@FrankH. : ["Casi toda la Sección 27"] (http://stackoverflow.com/questions/7066691/is-stdofstream-movable), para citar a Howard Hinnant. – MSalters

Respuesta

11

El objeto fstream no es copiable.

Si necesita registrar fstream s en un, puede declarar un std::vector<std::fstream*> y devolver la dirección del objeto. Recuerde que si guarda el puntero, debe asegurarse de que, cuando acceda, el objeto siga vivo.

+2

No es necesario copiar un objeto para moverlo a un contenedor: esta fue una restricción de C++ 2003. Es suficiente que el tipo se pueda mover, pero debe usar un objeto desde el cual se pueda mover, p. ya sea un temporal o el resultado de 'std :: move()'. –

+0

@ DietmarKühl es bueno saberlo. Definitivamente debo comenzar a aprender C++ 11 –

+1

Además, 'emplace_back' en' vector 'funciona bien en VS2013. (Aunque falla en GCC.) –

1

Un requisito básico para insertar un tipo en vector es que el objeto debe ser copiable, fstream no se puede copiar y, por lo tanto, se obtienen errores de compilación.

3

Para usar una clase con un vector, debe ser copiable. fstream no es.

Ver: C++ std::ifstream in constructor problem

Editar: Si es necesario tener múltiples referencias a la misma fstream, puede utilizar shared_ptr para gestionarlos. Pruebe algo como:

std::vector< std::shared_ptr<fstream> > TEST 
5

En C++ 2011, los objetos de flujo de hormigón son móviles. Howver, para tomar ventaja de esta o hay que hacer pasar una temporal o permitir que el objeto se mueva:

std::vector<std::ofstream> files; 
files.push_back(std::ofstream("f1")); 
std::ofstream file("f2"); 
files.push_back(std::move(file)); 

Tenga en cuenta que no se puede utilizar la variable file después de esto como la corriente se trasladó a files.

Cuestiones relacionadas