I tried to create for outputting the timing results and call any ofstream from pre-defined 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 it?
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;
As an std::ostream
is not copyable (copy constructor and assignment operator are marked deleted), you have to either construct the ofstream directly in the map (e.g. using std::map::emplace()
) or use move assignment.
There are basically two ways, either default-construct stream in the map (pre C++11), or call std::map::emplace()
to supply ofstream
constructor arguments.
Using default-construction (works even pre C++11):
map<string,ofstream> m;
// default-construct stream in map
ofstream& strm = m["test"];
strm.open("test_output");
strm << "foo";
Using emplacement:
// 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";
We can construct the stream outside of the map first, turn it into an rvalue by calling std::move()
and use move assignment operator to move it into 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");
Move assignment is less efficient than the other methods, because first a stream will be default-constructed in the map, just to be replaced by the move-assigned stream then.
Live demo of all three methods.
Note: Sample code omitts any error handling for brevity. State of stream should be checked after opening and after each stream operation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With