为什么 std::fill 使用 ForwardIterator,而不是 OutputIterator?

Why does std::fill use ForwardIterator, not OutputIterator?

本文关键字:OutputIterator ForwardIterator std fill 使用 为什么      更新时间:2023-10-16

(这个问题与为什么 std::max_element 需要转发迭代器具有相同的"问题模板"? 但答案必须不同,因为std::fill不会将迭代器返回到输出序列中。

std::fill被定义为仅在输出范围由一对转发迭代器给出时才起作用。但是,表面上相似的std::fill_n与输出迭代器配合使用。

当然,算法很简单

template<class OutIt, class T>
void fill(OutIt first, OutIt last, T value)
{
while (first != last) {
*first = value;
++first;
}
}

这个算法需要前向迭代器吗?我错过了什么?

输出迭代器没有可比性。未为输出迭代器定义==运算符和!=运算符。

你需要一个前向迭代器,因为它

满足输入迭代器的要求

支持EqualityComparable

使用输出迭代器,std::fill无法将firstlast进行比较:

while (first != last) {

不支持,用于输出迭代器。

std::fill_n避免这种比较,它只是使用计数器写入迭代器,所以它只需要一个输出迭代器。

OutputIterator没有"范围"的概念。因此,您必须提供重复计数。使用ForwardIterator,您可以处理一系列元素。

这些在语义上是不同的东西。fill_n用于从提供的迭代器开始添加一些元素。fill用于更改一系列元素。

以机械臂(例如back_inserter)为例。您可以插入比容器中更多的元素,因此last甚至没有意义。

OutputIterator为您提供了一个可以扔物体的地方。ForwardIterator对象必须存在。

从 cpp 首选项:

运算符* 与输出迭代器的唯一有效用法是在赋值的左侧:运算符* 可以返回一个代理对象,该对象定义一个成员运算符=(可以是模板)

这意味着您基本上无法从中读取,这与ForwardIterator形成对比:

转发迭代器是可以从指向的元素读取数据的迭代器。