Why can't ofstream be bound with bind?

464 Views Asked by At

I'd like to reduce code size by binding common arguments (including an open ofstream) to a function called multiple times but both clang and gcc refuse to compile this program:

#include "functional"
#include "fstream"
using namespace std;
void writer(ofstream& outfile, int a) {
    outfile << "asdf " << a;
}
int main() {
    ofstream outfile("test");
    writer(outfile, 3);
    auto writer2 = bind(writer, outfile, placeholders::_1);
    writer2(1);
    writer2(2);
    writer2(3);
    return 0;
}

Clang error doesn't look helpful but gcc gives:

/opt/local/gcc-4.9.1/include/c++/4.9.1/tuple:140:42: error: use of deleted function ‘std::basic_ofstream<char>::basic_ofstream(const std::basic_ofstream<char>&)’
  : _M_head_impl(std::forward<_UHead>(__h)) { }
                                      ^
In file included from testi.cpp:2:0:
/opt/local/gcc-4.9.1/include/c++/4.9.1/fstream:602:11: note: ‘std::basic_ofstream<char>::basic_ofstream(const std::basic_ofstream<char>&)’ is implicitly deleted because the default definition would be ill-formed:
     class basic_ofstream : public basic_ostream<_CharT,_Traits>
           ^

Am I doing something wrong or is binding an ofstream not possible (why not)?

2

There are 2 best solutions below

1
On BEST ANSWER

The error message you are receiving is pretty clear:

error: use of deleted function 
  ‘std::basic_ofstream::basic_ofstream(const std::basic_ofstream&)’
    : _M_head_impl(std::forward(__h)) { }

The copy constructor is deleted, so std::ofstream cannot be copied. If you want to wrap an argument to std::bind in a reference, use std::ref.

auto writer2 = bind(writer, ref(outfile), placeholders::_1);
1
On

Your code is legal C++11 if you move the stream into the bind:

auto writer2 = bind(writer, std::move(outfile), placeholders::_1);

If this still doesn't work for you, it is because gcc has not yet implemented movable streams. I know this work is in progress, but I do not know which gcc version it lands in.