There is a similar question to this one but it was not answered.
I am trying to create a map of std::ofstream
objects but I cannot build the code.
So far I have tried
//std::map<std::string, std::ofstream> my_files; //this fails
std::map<std::string, std::ofstream& > my_files;
for(auto & member: members){
filename=GetFileName();
//create the file
std::ofstream thefile(filename);
my_files[member.first]=thefile;
}
//Here I use the ofstreams in the map to write etc
I tried the first (commented) line and I got this error. Use of deleted function. So I change it to the line above, but I still get the same error error: use of deleted function ‘std::basic_ofstream<
How can I build a map of ofstream objects?
Note: In the similar question, someone suggested to use a map of strings but the reason to use a map of ofstream is that I am not going to be opening and closing the file everytime I want to do a minimal change to each.
CodePudding user response:
The problem is that a reference is not object by itself. A reference refers to some other object. So you cannot store a reference in a container.
You can solve this by replacing my_files[member.first]=thefile;
with:
my_files.emplace(member.first, std::ofstream(filename));
Also, replace std::map<std::string, std::ofstream& > my_files;
with:
std::map<std::string, std::ofstream > my_files; //removed the &
Modified Code
std::map<std::string, std::ofstream > my_files; //removed the &
for(auto & member: members){
filename=GetFileName();
my_files.emplace(member.first, std::ofstream(filename)); //ADDED THIS
}
CodePudding user response:
First of all, references cannot be stored in containers. But you seem to want to store the std::ofstream
itself, not a reference to it, anyway, since your std::ofstream
object is otherwise going to be destroyed at the end of the loop body leaving you with a dangling reference in the map, so:
std::map<std::string, std::ofstream > my_files;
Secondly, stream objects such as std::ofstream
are not copyable, so you cannot simply copy them into the map.
However, they are movable, so you can move them into the map:
my_files[member.first] = std::move(thefile);
(requires #include<utility>
) or alternatively, by constructing it directly in the assignment:
my_files[member.first] = std::ofstream(filename);
For explanation of std::move
if you haven't seen it before, see this question.