Why can't std::ostream be moved?

C++C++11Iostream

C++ Problem Overview


Clearly, streams can't be copied. It should be possible to move streams. According to 27.9.1.11 [ofstream.cons] paragraph 4 it is possible to move construct an std::ofstream (the same is true for std::ifstream, std::fstream, and the std::*stringstream variants). For example:

#include <iostream>
#include <fstream>
#include <string>

std::ofstream makeStream(std::string const& name) {
    return std::ofstream(name);
}

int main()
{
    std::ofstream out{ makeStream("example.log") };
}

Trying to move an std::ostream, e.g., to have a factory function creating an std::ofstream, an std::ostringstream, or some other stream according to a URN passed as argument doesn't work. std::ostream (well, the class template std::basic_ostream really) has a protected move constructor according to 27.7.3.1 [ostream].

Why can't std::ostream be moved itself?

C++ Solutions


Solution 1 - C++

Originally they were movable. This turned out to be a design flaw on my part, and discovered by Alberto Ganesh Barbati:

http://cplusplus.github.io/LWG/lwg-defects.html#911

The issue shows a few examples where ostream gets moved and/or swapped, and the results are surprising, instead of expected. I was convinced that these types should not be publicly movable nor swappable by this issue.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDietmar K&#252;hlView Question on Stackoverflow
Solution 1 - C++Howard HinnantView Answer on Stackoverflow