Why does the following not work:
#include <iostream>
#include <fstream>
#include <stack>
std::stack<std::ifstream> s;
-PT
Why does the following not work:
#include <iostream>
#include <fstream>
#include <stack>
std::stack<std::ifstream> s;
-PT
std::stack
(like all STL containers) requires that its contained type be "assignable". In STL-speak, that means that it must have a copy constructor and an operator=
. std::ifstream
has neither of these.
You can imagine why you would not want to be able to copy and assign I/O streams; the semantics of what should happen when there are two copies of the same stream are not obvious. Should a read from or write to one copy affect the position of the other copy? Should closing one stream close the other? etc.
If you want to have "a container of std::ifstream
s", then what you really should make is "a container of std::ifstream*
s". Non-const pointers are always assignable. The caveat is that in this case of course you have to make sure that you delete the pointers yourself before destructing the container, since the container will not do that for you.
Backing up Tyler here (after voting +1).
The stl containers make copies all over the place of the objects you give them. If you want, you can deal with this by giving them special objects with carefully crafted copy constructors and destructurs with reference counting and whatnot.
Generally, I find that way too much trouble. Just as a rule of thumb, only use small objects in the containers. If you want to make a stack of structures or classes, use pointers to them instead.
Because streams are non copyable you can tecxhnicaly put them into standard containers.
But we can get around that by storeing pointers to the stream. But you dont want to store pointers to streams (especially if they are dynamically allocated) in a standard container. So we look to boost for a solution.
Boost has the concept of pointer containers.
This allows you to dynamically allocate an object and store the pointer in the pointer container which then takes ownership of the object and gives you access to the dynamic object as if it were the object (rather than a pointer).
Because the pointer container takes ownership you don;t need to worry about deleting the object. The container will do that.
Because it gives access to the contained objects as objects rather than pointers it allows you to use the stream in standard algorithms in a more natural fashon (campared with a container of pointers).