Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does std::copy_n take a template parameter instead of std::size_t?

Tags:

c++

c++11

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);
like image 210
DeiDei Avatar asked Dec 30 '15 02:12

DeiDei


2 Answers

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

C++11 §25.1/12:

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 of a+n is the same as that of

X tmp = a;
advance(tmp, n);
return tmp;

and that of b-a is the same as of return 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.

like image 200
Cheers and hth. - Alf Avatar answered Nov 14 '22 20:11

Cheers and hth. - Alf


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.

like image 31
coincoin Avatar answered Nov 14 '22 18:11

coincoin