Why can't I move std::ofstream?

2019-01-12 09:00发布

问题:

Looking at previous answers on SO, it seems that while std::ostream is not be movable, std::ofstream should be. However, this code

#include <fstream>

int main()
{
    std::ofstream ofs;
    std::ofstream ofs2{std::move(ofs)};
}

does not seem to compile in any version of gcc or clang I tried (with either --std=c++11 or --std=c++14). The compiler error varies somewhat, but here's what I get for gcc 4.9.0

6 : error: use of deleted function 'std::basic_ofstream::basic_ofstream(const std::basic_ofstream&)'

Is this the expected behavior, according to the standard?

Note that a very similar question was asked before ( Is std::ofstream movable? ) but seems the standard has changed since then ( as detailed in Why can't std::ostream be moved? ) rendering those answers outdated. Certainly, none of those answers explains why the code above does not compile.

Came across this issue when trying to use containers of ofstream, which does not work because of the above.

回答1:

According to the standard

27.9.1.11 basic_ofstream constructors

or, its more "readable" version http://en.cppreference.com/w/cpp/io/basic_ofstream/basic_ofstream , std::basic_ostream<> has a move constructor, so the code should compile.

clang++ 3.5 compiles it with -std=c++11 or -std=c++1y. Also gcc5 compiles it, so probably it is not implemented in libstdc++ for gcc < 5

Interestingly, the lack of move semantics is not mentioned on gcc's stdlibc++ implementation https://gcc.gnu.org/onlinedocs/libstdc++/manual/status.html#status.iso.2014

See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54316 for a bug report, thanks to @BoBTFish for pointing out. It is confirmed that the issue was fixed in gcc5.