2014-11-19 2 views
1

Я хотел бы, чтобы уменьшить размер кода путем связывания общих аргументов (в то числе открытого ofstream) к функции называется несколько раз, но как лязга и G отказывается скомпилировать эту программу:Почему нельзя связать связь с привязкой?

#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 ошибка не выглядит полезно, но НКУ дает:

/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> 
     ^

я делаю что-то неправильно или связывание ofstream не представляется возможным (почему нет)?

ответ

7

сообщение об ошибке вы получаете довольно ясно:

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

Конструктор копирования будет удален, так std::ofstream не могут быть скопированы. Если вы хотите обернуть аргумент std::bind в ссылке, используйте std::ref.

auto writer2 = bind(writer, ref(outfile), placeholders::_1); 
+0

Спасибо, я бы это обработал автоматически, поскольку bind принимает свои аргументы как && (согласно cppreference). – user3493721

+0

@ user3493721, он принимает аргументы путем перенаправления ссылок, но затем он копирует эти аргументы. [cppreference] (http://en.cppreference.com/w/cpp/utility/functional/bind) объясняет, что если вы продолжаете читать: _ «один объект на каждый из« args ... », типа' std: : decay :: type', аналогично построенный из 'std :: forward (arg_i)' "_ –

3

Ваш код является законным C++ 11, если вы двигаться поток в безвыходном:

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

Если это все еще не работает для вас, это потому, что GCC не имеет еще реализованы движимые потоки. Я знаю, что эта работа продолжается, но я не знаю, какую версию gcc она приземлится.

+2

Он реализован, но только в багажнике, так будет в выпуске GCC 5 –

Смежные вопросы