loading fstreams into a std::vector in c++
Asked Answered
K

5

6

This is a simple and complex question at the same time.

This compiles:

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

This does not compile:

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

Is there any particular reason? Is there a way for me to get a dynamic list of fstreams?

The error message:

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 ==========
Kaiserslautern answered 27/3, 2012 at 12:7 Comment(3)
In C++, this will become possible: IOStreams are movable, and vector will support movable types.Injector
@MSalters: A reference to the part of the C++11 standard which states the above might be helpful ;-)Verner
@Verner : "Pretty much all of Section 27", to quote Howard Hinnant.Injector
E
11

The object fstream is not copyable.

If you need to record fstreams in a vector you can declare a std::vector<std::fstream*> and push back the address of the object. Remember that if you save the pointer, then you must ensure that, when you access it, the object is still alive.

Eponymy answered 27/3, 2012 at 12:11 Comment(3)
An object doesn't have to be copyable to be moved into a container: this was a C++ 2003 restriction. It is sufficient for the type to be movable but you need to use an object which can be moved from, e.g. either a temporary or the result of std::move().Royalty
@DietmarKühl good to know. I must definitely start learning C++11Eponymy
Also, emplace_back into vector<ifstream> works fine in VS2013. (Though fails in GCC.)Halfblooded
A
9

In C++ 2011 the concrete stream objects are movable. Howver, to take advantage of this you either need to pass a temporary or allow the object to be moved:

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

Note that you can't use the file variable after this as the stream was moved into files.

Annabelleannabergite answered 27/3, 2012 at 12:35 Comment(0)
S
3

To use a class with a vector, it must be copyable. fstream is not.

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

Edit: If you need to have multiple references to the same fstream, you can use shared_ptr to manage them. Try something like:

std::vector< std::shared_ptr<fstream> > TEST
Snubnosed answered 27/3, 2012 at 12:12 Comment(0)
W
1

A basic requirement for a type to be pushed into vector is that the object should be copyable, fstream is not copyable and hence you get compiler errors.

Weatherley answered 27/3, 2012 at 12:12 Comment(0)
P
0

Like others have mentioned, fstream is not copyable. You could just do:

vector<fstream> TEST;
TEST.push_back(fstream()); //fstream is created in the vector, no copy needed

And use like this:

fstream& A = TEST[0];

And even iterate like this:

for(fstream& S : TEST){
...
}
Presignify answered 21/2, 2023 at 14:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.