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 ==========
shieldfoss
  • 886
  • 2
  • 12
  • 22
  • In C++, this will become possible: IOStreams are movable, and vector will support movable types. – MSalters Mar 27 '12 at 13:03
  • @MSalters: A reference to the part of the C++11 standard which states the above might be helpful ;-) – FrankH. Mar 27 '12 at 13:27
  • 1
    @FrankH. : ["Pretty much all of Section 27"](http://stackoverflow.com/questions/7066691/is-stdofstream-movable), to quote Howard Hinnant. – MSalters Mar 27 '12 at 13:42

5 Answers5

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.

Luca Martini
  • 1,434
  • 1
  • 15
  • 35
  • 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()`. – Dietmar Kühl Mar 27 '12 at 12:40
  • @DietmarKühl good to know. I must definitely start learning C++11 – Luca Martini Mar 27 '12 at 13:26
  • 1
    Also, `emplace_back` into `vector` works fine in VS2013. (Though fails in GCC.) – polkovnikov.ph May 29 '14 at 12:33
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.

Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380
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
Community
  • 1
  • 1
stanwise
  • 2,392
  • 1
  • 15
  • 21
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.

Naveen
  • 74,600
  • 47
  • 176
  • 233
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){
...
}