-1

My plan is to build a fileContainer that consists mainly of a std::map that associate specific files to an ID. Each file has for attributes a ofstream, a path (string) and a few other information.

The problem is that an ofstream cannot be copied (Why copying stringstream is not allowed?) and cannot even be moved (Why can't std::ostream be moved?). One can therefore not create file objects to then insert them into the map of the fileContainer.

What I am trying to do is something like

file f(arguments...); // create a `file`
FC.insert(f);         // Note the FC is a global singleton of class `fileContainer`
...
{
   file& f = FC.getFile(fileID); // find a specific file in the file container
   f.open();
   f.write(s1);
   f.write(s2);
   f.write(s3);
   f.close();
}

I fail to see how such functionality could be achieved without having to copy or move a stream. Can you help me out to build this type of functionality?

Response to @πάνταῥεῖ comment

My code can produce about 20 different types of files. The types of files (which I above call ID) that are actually being produce depends upon the user input.

My goal is to have a fileContainer in which, I insert file objects. Those file objects are created while I read the input. Each file object match to a file ID. For any given file object a single file is being produced but for others, several files are being produced (information that can be gathered only during the process).

During the process, I would just look at whether a given ID is present in the fileContainer and if it is, then I write to it the associated file.

I already have a working version of the code, the issue is that it does not compile on every machine (looks like some compilers are fine with moving streams while others aren't)

Remi.b
  • 17,389
  • 28
  • 87
  • 168

1 Answers1

2

If you only need std::ofstream

No problem! These are moveable.


If you need any std::ostream

Since std::ostreams cannot be copied or moved, your only option is to go back in time and store pointers instead. Use dynamic allocation to get fine control over the lifetime of your stubborn stream objects.

Abstracting away your custom container, a basic example looks like this:

std::vector<std::unique_ptr<std::ostream>> container;
container.push_back(std::make_unique<std::ostringstream>());
container.push_back(std::make_unique<std::ofstream>("/tmp/lol"));

…and so forth.

Nice, huh? #c++

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055