So simple question.
template<class InputIt, class Size, class OutputIt>
OutputIt copy_n(InputIt first, Size count, OutputIt result);
Why does std::copy_n
take a type for the number of elements it's going to copy instead of simply std::size_t
? I just can't think of a reason.
template<class InputIt, class OutputIt>
OutputIt copy_n(InputIt first, std::size_t count, OutputIt result);
Speculating about original rationales is mostly futile in such a case, but with this design copy_n
can be invoked with a negative count of e.g. int
or ptrdiff_t
type, in which case it simply does nothing, and that must surely have been clear to the standardization committee's members, who are pretty competent folks.
One additional advantage is that with special iterators, such as input and output iterators, the size might be larger than any possible pointer difference, and hence possibly larger than size_t
can represent. E.g. this is so for files larger than 4GB in 32-bit Windows. The definition of copy_n
is expressed in terms of apparent pointer/iterator arithmetic, “For each non-negative integer i < n
, performs *(result + i) = *(first + i)
”, which would seem to relegate this advantage to very special cases indeed, but the notation accommodates pure input and output iterators as explained in
” In the description of the algorithms operators
+
and-
are used for some of the iterator categories for which they do not have to be defined. In these cases the semantics ofa+n
is the same as that ofX tmp = a; advance(tmp, n); return tmp;
and that of
b-a
is the same as ofreturn distance(a, b)
;
The genericity of the design has no inherent advantage, rather it's a disadvantage in itself in that it's more verbose and generates less easily understood diagnostics for incorrect usage code. Its advantages include the two ones listed above. Evidently the committee felt that these advantages, and perhaps others (?), outweighed the inherent disadvantages of having Size
as a template parameter.
I would guess it is because of genericity.
Containers size_type
in C++ are usually size_t
. But if you use a custom container, or use custom allocators, that might not be the case hence the template parameter.
For a custom container, size_type
does not have to be a typedef to size_t
(it has to be an unsigned integer large enough to represent all positive values of difference_type
).
For STL containers, size_type
is a typedef to allocator::size_type
which is size_t
for the default allocator. But the type can be different if you specify a custom allocator.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With