алгоритм std::move

299
11 февраля 2017, 07:45

Испортит ли эта инструкция данные в файле?

std::ifstream in("in.txt");
std::ofstream out("out.txt");
std::move(
  std::istream_iterator<int>(in),
  std::istream_iterator<int>(),
  std::ostream_iterator<int>(out)
);
Answer 1

Нет, конечно, данные в файле не испортятся (если речь идет о читаемом файле in).

Отличие алгоритма std::move от, скажем, алгоритма std::copy заключается только в том, что операция, применяемая к каждой паре соответствующих элементов диапазонов, это

*dst_iterator = std::move(*src_iterator);

а не просто

*dst_iterator = *src_iterator;

И поведение алгоритма std::move в данном случае будет зависеть от поведения этого выражения для dst_iterator типа std::ostream_iterator<int>.

Оператор * в std::ostream_iterator - это no-op, просто возвращающий ссылку на сам итератор, следовательно все зависит только от поведения std::ostream_iterator<>::operator= в данном контексте. А он существует только в одной форме

ostream_iterator &operator=(const T &value);

Т.е. даже в присутствии std::move вызваться будет все равно "обычный" оператор присваивания (тот же самый, который вызывался бы в std::copy) и поведение алгоритма std::move ничем не будет отличаться от поведения алгоритма std::copy.

Отдельно стоит заметить, что оператор присваивания в этом контексте, какие бы формы он ни предоставлял, все равно уже не имеет никакой возможности физически доступиться до исходного файла и как-то "испортить" его. Причем эта возможность отсечена уже на уровне std::istream_iterator.

Answer 2

Итератор std::istream_iterator<int>(in) считывает данные из файла. Его работа совершенно никак не зависит от того, в какой функции или алгоритме он вызывается. То есть этот итератор ничего не знает о том, где он вызывается, вызывается ли он в алгоритме std::move или в каком-нибудь ином алгоритме. Он обеспечивает получение копии объекта, считанного из потока с помощью оператора operator >>.

Более того, так как фундаментальные типы не имеют конструкторов, то есть ни конструктора копирования, ни конструктора перемещения, то при копировании объекта с исходным объектом ничего не происходит. Поэтому более логично вместо алгоритма std::move, который в данном контексте не несет никакой семантической нагрузки, использовать алгоритм std::copy.

READ ALSO
Оптимизация JOIN запросов

Оптимизация JOIN запросов

Помогите ускорить выборку из базы Mysql При выборке 10 записей уходит 25 секунды!

315
Dbeaver не отображает данные таблицы

Dbeaver не отображает данные таблицы

При попытке отобразить данные выпадает ошибка

602