且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

为什么range的算法与std的迭代器不兼容?

更新时间:2023-11-09 08:44:34

对我来说,通用算法copy不需要关心目标迭代器的类型,只要它满足输出迭代器的要求即可.

To me, the generic algorithm copy shouldn't care about the destination iterator type as long as it meets the requirements of output iterator.

这是正确的.不是ranges::copy可以识别ranges::ostream_iterator而不是std::ostream_iterator.正是Ranges对OutputIterator 的概念有了一个完善的概念,例如ranges::ostream_iterator可以对OutputIterator进行建模,而std::ostream_iterator 则不能.

This is correct. It's not that ranges::copy somehow recognizes ranges::ostream_iterator and not std::ostream_iterator. It's that Ranges has a refined concept for what an OutputIterator is, such that ranges::ostream_iterator does model OutputIterator but std::ostream_iterator does not.

具体来说, 需要 WeaklyIncrementable<O> 可以优化 SemiRegular<O> ,需要DefaultConstructible. ranges::ostream_iterator 默认是可构造的,但 std::ostream_iterator 则不是.

Specifically, ranges::copy() requires WeaklyIncrementable<O> which refines SemiRegular<O> which requires DefaultConstructible. ranges::ostream_iterator is default constructible, but std::ostream_iterator is not.

因此失败.

P0896 中,基于范围的copy()算法的输出迭代器确实需要WeaklyIncrementable(因此也需要DefaultConstructible)-但是通过在std::ostream_iterator中添加默认构造函数来解决此不匹配问题(请参见第70页).

In P0896, the range-based copy() algorithm does require WeaklyIncrementable (and thus DefaultConstructible) for its output iterator - but addresses this mismatch by also adding a default constructor to std::ostream_iterator (see page 70).

请注意,范围-v3/范围TS/范围提议概念OutputIterator与标准库的OutputIterator现有概念是分开的. std::ostream_iterator不会为前者建模,而 可以为后者建模-因此,今天将std::copystd::ostream_iterator一起使用是完全可以的.在P0896之后,将ranges::copystd::ostream_iterator一起使用也可以-因为建议对std::ostream_iterator进行更改.

Note that the range-v3/Ranges TS/Ranges Proposal concept OutputIterator is separate from the standard library's existing concept of OutputIterator. std::ostream_iterator does not model the former but it does model the latter - so using std::copy with a std::ostream_iterator today is perfectly fine. And post-P0896, using ranges::copy with a std::ostream_iterator will also be fine - because of the proposed changes to std::ostream_iterator.