为什么 std::copy_n 采用模板参数而不是 std::size_t

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

本文关键字:std size 参数 copy 为什么      更新时间:2023-10-16

这么简单的问题。

template<class InputIt, class Size, class OutputIt>
OutputIt copy_n(InputIt first, Size count, OutputIt result);

为什么std::copy_n要复制的元素数量采用类型,而不是简单地std::size_t?我只是想不出原因。

template<class InputIt, class OutputIt>
OutputIt copy_n(InputIt first, std::size_t count, OutputIt result);
在这种情况下,

推测原始理由大多是徒劳的,但是通过这种设计,copy_n可以用负计数调用,例如 intptrdiff_t类型,在这种情况下,它什么都不做,标准化委员会的成员肯定很清楚,他们都是非常有能力的人。


另一个优点是,对于特殊迭代器(如输入和输出迭代器(,大小可能大于任何可能的指针差异,因此可能大于size_t可以表示的大小。 例如,对于 32 位 Windows 中大于 4GB 的文件,情况就是如此。copy_n的定义用明显的指针/迭代器算术表示,"对于每个非负整数i < n,执行*(result + i) = *(first + i)",这似乎将这种优势降级到非常特殊的情况,但符号容纳纯输入和输出迭代器,如

C++11 §25.1/12:

"> 在算法的描述中,运算符+-用于某些迭代器类别,其中 不必定义它们。在这些情况下,a+n的语义与

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

b-a的与return distance(a, b)相同;


设计的通用性没有固有的优势,相反,它本身就是一个缺点,因为它更冗长,并且为不正确的使用代码生成不太容易理解的诊断。它的优点包括上面列出的两个。显然,委员会认为这些优点,也许还有其他优点(?(,超过了将Size作为模板参数的固有缺点。

我猜这是因为通用性
size_type C++的容器通常是size_t的。但是,如果您使用自定义容器或使用自定义分配器,则可能不是这种情况,因此模板参数。

对于自定义容器,size_type不必是要size_t的 typedef(它必须是 an unsigned integer large enough to represent all positive values of difference_type (。

对于 STL 容器,size_type 是要allocator::size_type的 typedef,默认分配器size_t。但是,如果指定自定义分配器,则类型可能会有所不同。