Страницы

Поиск по вопросам

вторник, 31 декабря 2019 г.

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

#cpp


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

std::ifstream in("in.txt");
std::ofstream out("out.txt");

std::move(
  std::istream_iterator(in),
  std::istream_iterator(),
  std::ostream_iterator(out)
);

    


Ответы

Ответ 1



Нет, конечно, данные в файле не испортятся (если речь идет о читаемом файле in). Отличие алгоритма std::move от, скажем, алгоритма std::copy заключается только в том, что операция, применяемая к каждой паре соответствующих элементов диапазонов, это *dst_iterator = std::move(*src_iterator); а не просто *dst_iterator = *src_iterator; И поведение алгоритма std::move в данном случае будет зависеть от поведения этого выражения для dst_iterator типа std::ostream_iterator. Оператор * в 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.

Ответ 2



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

Комментариев нет:

Отправить комментарий