I'm assuming that there is a std::copy_n
so that this can work with input iterators. Is there some reason why there is no std::move_n
for the same reason?
-
`std::copy_n()` works with the same types of iterators as `std::copy()`. They both take *InputIterator*s as input. The only difference is that `std::copy()` takes 2 input iterators denoting a range, whereas `std::copy_n()` takes 1 input iterator and a count. Not all situations have 2 iterators available to iterate between, sometimes a count makes more sense. – Remy Lebeau Apr 03 '19 at 19:04
2 Answers
I think the answer is probably pretty mundane.
std::copy
existed forever, it was the only one of these algorithms in C++03.
N1377 (2002) added move semantics into the language and also introduced the algorithms std::move()
and std::move_backward()
to mirror the existing std::copy()
and std::copy_backward()
. Those were the only copying algorithms in existence - so those were the only ones that got move
versions.
N2569 (2008) added a bunch more algorithms, most of which existed in the original Standard Template Library implementation - this is where std::copy_n()
and std::copy_if()
came from. Since the premise of the paper was a bunch of algorithms that have been around and used for years, it couldn't have included std::move_n()
or std::move_if()
. It seems that this simply wasn't considered.
I'm guessing if these happened in the opposite order, we might have had std::move_n()
today. But at this point, it might not be worth adding. Since, std::copy_n()
isn't even used super often and move_n
is very easy to implement:
template< class InputIt, class Size, class OutputIt>
OutputIt move_n(InputIt first, Size count, OutputIt result)
{
return std::copy_n(std::make_move_iterator(first), count, result);
}

- 286,269
- 29
- 621
- 977
-
-
@Adrian [That proposal](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0040r3.html) (2016) chose to cover both? – Barry Apr 03 '19 at 21:57
There is a std::make_move_iterator
to adapt any iterator into providing an rvalue.
Sending an adapted input iterator to std::copy_n
will achieve the desired effect, without much added noise.

- 165,132
- 21
- 377
- 458
-
2
-
1@RemyLebeau yes there is an [algorithm `std::move`](https://en.cppreference.com/w/cpp/algorithm/move) – Guillaume Racicot Apr 03 '19 at 19:05
-
1Ultimately, I guess no one considered `move_n` a common enough operation to warrant a shorthand. – StoryTeller - Unslander Monica Apr 03 '19 at 19:11
-
@Adrian C++ library code has a busload of overloads and near-repetitions to make the code more expressive. It is not the reason to add definitions of course. – Euri Pinhollow Apr 03 '19 at 20:16
-
I am not sure, but there could be still a difference between `std::move[range]` (`std::move_n`) and `std::copy` (`std::copy_n`). `std::move_n` could be conventionally marked `noexcept`. `std::move[range]` is not marked `noexcept` (I don't know why) but it could. Well maybe not because, that is true only if moves are really moves (destructive) in assignment. Which one doesn't know in advance. The point is that `std::move` and `std::move_n` could be more specific at detecting the noexceptness of the move assigment, if present. – alfC Aug 22 '21 at 21:53