【问题标题】:STL fill and forward iteratorSTL 填充和转发迭代器
【发布时间】:2013-04-23 19:04:37
【问题描述】:

根据大多数 C++ 参考资料,例如 cplusplus.com,forward iterators 不需要可分配(我的意思是,尊重左值)。但是,对于一些需要写入值的 STL 算法,例如std::fill(也有std::generate 等),规范使用了前向迭代器:

template <class ForwardIterator, class T>
  void fill (ForwardIterator first, ForwardIterator last, const T& val);

而等效行为需要左值取消引用:

template <class ForwardIterator, class T>
  void fill (ForwardIterator first, ForwardIterator last, const T& val)
{
  while (first != last) {
    *first = val;
    ++first;
  }
}

因此,它实际上是使用单次传递的可变前向迭代器。

现在的问题是:

(1) 为什么不明确说明在这些情况下使用的前向迭代器是可变的?

(2)更新:我发现下面的问题很愚蠢:我暂时忘记了输出迭代器不需要支持相等比较。无论如何,上述问题仍然存在。

为什么std::fillstd::generate 等使用前向迭代器而不是输出迭代器,而它们实际上并不需要多次传递? (例如,std::copy 只需要输出迭代器。原理是什么?)

【问题讨论】:

  • forward iterators are not required to be assignable,你是怎么确定的?我很确定它们是可分配的。
  • @JesseGood 出于实际目的,它们几乎总是可赋值的,但如果您阅读参考文献cplusplus.com/reference/iterator/ForwardIterator/…,则不是。
  • @JesseGood 我也在 SO 上找到了这个:stackoverflow.com/questions/14058642/…
  • 感谢您的链接,我不知道这一点。该链接还链接到this SO question,我认为它可以回答您的问题。
  • @JesseGood 谢谢,读起来很有趣。在阅读了您提到的线程后,这个问题对我来说更像是标准中的缺陷。

标签: c++ stl iterator


【解决方案1】:

来自签名

template <class ForwardIterator, class T>
void fill (ForwardIterator first, ForwardIterator last, const T& val);

你不能推断ForwardIteratorforward iterator 中描述的迭代器。但是,如果您阅读参数说明,您会发现firstlast必须是

Forward Iterators 到元素序列中的初始和最终位置支持分配 T 类型的值

(我强调)。因此,仅满足前向迭代器要求的前向迭代器不是有效参数。

【讨论】:

  • 是的,这很好。但是从标准的角度来看,签名很棘手。
  • 另一种方法是为支持分配给指向元素的前向迭代器引入一个新名称。
【解决方案2】:

考虑到fill 的规范是(取消引用的)迭代器可以从T 分配,这对我来说似乎并不奇怪。输出迭代器是不够的,因为它无法确定范围结束,因此选择了带有要求的 forward_iterator

您会注意到fill_n确实使用输出迭代器,因为不需要迭代器比较来确定要填充的序列的结尾。

【讨论】:

  • 我认为 OP 的观点是,前向迭代器的概念是必需的,但不足以充分指定参数类型的要求。 “输出迭代器”也是如此;只有要求参数是both,我们才能得到正确的语义。换句话说,有些前向迭代器无法调用 std::fill
猜你喜欢
  • 1970-01-01
  • 2013-04-16
  • 2011-07-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-16
  • 2012-07-20
相关资源
最近更新 更多