Почему я не могу переместить std:: ofstream?
Глядя на предыдущие ответы на SO, кажется, что, хотя std::ostream
не является подвижным, std::ofstream
должен быть. Однако этот код
#include <fstream>
int main()
{
std::ofstream ofs;
std::ofstream ofs2{std::move(ofs)};
}
похоже, не компилируется ни в одной из версий gcc или clang, которые я пробовал (с -std = С++ 11 или -std = С++ 14). Ошибка компилятора несколько отличается, но вот то, что я получаю для gcc 4.9.0
6 : error: use of deleted function 'std::basic_ofstream::basic_ofstream(const std::basic_ofstream&)'
Является ли это ожидаемым поведением в соответствии со стандартом?
Обратите внимание, что ранее был задан очень похожий вопрос (Is std:: ofstream movable?), но кажется, что стандарт изменился с тех пор (как подробно описано в
Почему нельзя переместить std:: ostream?), чтобы эти ответы устарели. Конечно, ни один из этих ответов не объясняет, почему приведенный выше код не компилируется.
Произошла ошибка при попытке использовать контейнеры ofstream
, которые не работают из-за вышеперечисленного.
Ответы
Ответ 1
Согласно стандарту
27.9.1.11 конструкторы basic_ofstream
или, более "читаемая" версия http://en.cppreference.com/w/cpp/io/basic_ofstream/basic_ofstream, std::basic_ostream<>
имеет конструктор перемещения, поэтому код должен компилироваться.
clang++ 3.5 скомпилирует его с помощью -std=c++11
или -std=c++1y
. Также gcc5 компилирует его, поэтому, вероятно, он не реализован в libstdС++ для gcc < 5
Интересно, что отсутствие семантики перемещения не упоминается в реализации gcc stdlibС++ https://gcc.gnu.org/onlinedocs/libstdc++/manual/status.html#status.iso.2014
См. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54316 для отчета об ошибке, благодаря @BoBTFish для указания. Подтверждено, что проблема была исправлена в gcc5.