2

"Handling map of files in c++" says no, one shall use std::map<std::string, std::ofstream*>, but this leads to the new and delete actions, which is not so neat.

Since "Is std::ofstream movable? Yes!" and it's possible to "std::map<>::insert using non-copyable objects and uniform initialization", is it possible to handle a collection of ofstream using std::map? so that one won't worry about closing filestreams and delete to release memory.

I can compromise that during using std::map<std::string, std::ofstream>, only create, use (it to write) and close, not to copy it.

Community
  • 1
  • 1
athos
  • 6,120
  • 5
  • 51
  • 95
  • "so that one won't worry about closing filestreams and delete to release memory". That's what smart pointers are for (if move semantics doesn't work for you, or you want polymorphic streams). – n. m. could be an AI Oct 16 '16 at 19:16
  • but ofstream itself also does this, right? if the map is out of scope, its destructor will be called, which again will call all element's destructor, that is the ofstream's, then all files will be closed properly. – athos Oct 17 '16 at 00:25

1 Answers1

3

Yes it is possible. See sample code below.

I can compromise that during using std::map<std::string, std::ofstream>, only create, use (it to write) and close, not to copy it.

They are not copyable, so in your final comment, you are correct, you will be unable to copy it. You can move assign though, if that's what you want to do.

#include <iostream>
#include <fstream>
#include <map>

int main()
{
    std::map<std::string, std::ofstream> map;
    map.emplace("foo", std::ofstream("/tmp/foo"));
    map.emplace("bar", std::ofstream("/tmp/bar"));

    map["foo"] << "test";
    map["foo"].flush();

    std::ifstream ifs("/tmp/foo");
    std::string data;
    ifs >> data;

    std::cout << data << '\n';

    return 0;
}

Output:

test

Steve Lorimer
  • 27,059
  • 17
  • 118
  • 213
  • 2
    You can omit the move operation, this code will construct an ofstream object and move it into the std::map storage. 'map.emplace("foo", "/tmp/foo");' will construct the object in-place. – TimVdG Oct 16 '16 at 20:29