Can't we manage std :: map <string, ofstream>?
I tried to create to output sync results and call any of the threads from a predefined string:
#include <cstring>
#include <map>
#include <fstream>
using namespace std;
int main(void) {
map<string,ofstream> Map;
ofstream ofs("test_output");
string st="test";
Map[st] = ofs;
return 0;
}
I got the following error; how can i fix this?
a.cpp: In function ‘int main()’: a.cpp:11:8: error: use of deleted function ‘std::basic_ofstream<_CharT, _Traits>& std::basic_ofstream<_CharT, _Traits>::operator=(const std::basic_ofstream<_CharT, _Traits>&) [with _CharT = char; _Traits = std::char_traits<char>]’ Map[s]=ofs; ^ In file included from a.cpp:3:0: /usr/include/c++/5/fstream:744:7: note: declared here operator=(const basic_ofstream&) = delete; ^ In file included from a.cpp:3:0: /usr/include/c++/5/fstream:744:7: note: declared here operator=(const basic_ofstream&) = delete;
source to share
Since it is std::ostream
not copied (copy constructor and assignment operator are marked as deleted), you need to either build the stream directly on the map (for example using std::map::emplace()
) or use move assignment.
Build in place
Basically there are two ways, the default is to build the stream on the map (pre C ++ 11) or call std::map::emplace()
to provide constructor arguments ofstream
.
Using default build (works even up to C ++ 11):
map<string,ofstream> m;
// default-construct stream in map
ofstream& strm = m["test"];
strm.open("test_output");
strm << "foo";
Using placement:
// 1st parameter is map key, 2nd parameter is ofstream constructor parameter
auto res = m.emplace("test", "test_output");
auto& strm = res.first->second;
strm << "bar";
Move destination
First, we can build a stream outside of the map, turn it into an rvalue by calling std::move()
and use the move assignment operator to move it to the map:
map<string,ofstream> m;
ofstream strm("test_output");
m["test"] = std::move( strm );
// strm is not "valid" anymore, it has been moved into the map
We can even get rid of std::move()
if we directly create the stream as an rvalue :
m["test"] = ofstream("test_output");
Transfer assignment is less efficient than other methods because the stream will be configured as the default on the map first, instead it will be replaced by the traffic assigned stream.
Live demonstration of all three methods.
Note. ... A sample example helps reduce errors for brevity. The state of the stream should be checked after opening and after each operation of the stream.
source to share
This is due to the fact that you cannot copy ostream
, you can only transfer it. You are getting this error because the copy assignment operator has been removed. Instead, the card must own the stream:
Map[st] = std::move(ofs);
This now also means that you have to be careful when repeating your card. You must avoid copies and also avoid stealing property from the map.
Please note that is using namespace std;
not recommended.
source to share