2012-03-27 3 views
5

Questa è una domanda semplice e complessa allo stesso tempo.caricamento di stream in un file std :: vector in C++

Questo compila:

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

Questo non può essere compilato:

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

C'è un motivo particolare? C'è un modo per me di ottenere un elenco dinamico di flussi?

Il messaggio di errore:

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

In C++, questo diventa possibile: IOStreams sono mobili e il vettore supporterà i tipi mobili. – MSalters

+0

@MSalters: un riferimento alla parte dello standard C++ 11 che afferma quanto sopra potrebbe essere utile ;-) –

+1

@FrankH. : ["Praticamente tutta la sezione 27"] (http://stackoverflow.com/questions/7066691/is-stdofstream-movable), per citare Howard Hinnant. – MSalters

risposta

11

L'oggetto fstream non è copiabile.

Se è necessario registrare fstream s in un vector è possibile dichiarare un std::vector<std::fstream*> e respingere l'indirizzo dell'oggetto. Ricorda che se salvi il puntatore, devi assicurarti che, quando lo accederai, l'oggetto sia ancora vivo.

+2

Un oggetto non deve essere copiato per essere spostato in un contenitore: questa era una restrizione C++ 2003. È sufficiente che il tipo sia mobile ma è necessario utilizzare un oggetto che può essere spostato da, ad es. o un risultato temporaneo o il risultato di 'std :: move()'. –

+0

@ DietmarKühl buono a sapersi. Devo assolutamente iniziare ad imparare C++ 11 –

+1

Inoltre, 'emplace_back' in' vector 'funziona bene in VS2013. (Anche se non riesce in GCC.) –

1

Un requisito di base per un tipo da inserire nel vettore è che l'oggetto deve essere copiato, fstream non è copiabile e quindi si verificano errori del compilatore.

3

Per utilizzare una classe con un vettore, deve essere copiabile. fstream no.

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

Edit: Se hai bisogno di avere più riferimenti alla stessa fstream, è possibile utilizzare shared_ptr per la loro gestione. Prova qualcosa del tipo:

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

In C++ 2011 gli oggetti del flusso di calcestruzzo sono mobili. Ad ogni modo, per approfittare di questo vi sia bisogno di passare un temporaneo o consentire l'oggetto da spostare:

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

Notare che non è possibile utilizzare la variabile file dopo questo come il flusso è stato spostato in files.