为什么range的算法与std的迭代器不兼容? [英] Why aren't ranges' algorithms compatible with std's iterators?
问题描述
#include <vector>
#include <iostream>
#include <range/v3/all.hpp>
int main()
{
auto coll = std::vector{ 1, 2, 3 };
ranges::copy(
coll,
ranges::ostream_iterator<int>{ std::cout, ", " }
); // ok
ranges::copy(
coll,
std::ostream_iterator<int>{ std::cout, ", " }
); // error
}
该问题显示在上面的代码中.我使用 ranges-v3-0.3.7 .
The issue is shown in the code above. I use ranges-v3-0.3.7.
对我来说,通用算法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.
如果是这样,为什么range的算法与std的迭代器不兼容?
If so, why aren't ranges' algorithms compatible with std's iterators?
推荐答案
对我来说,通用算法
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::copy
与std::ostream_iterator
一起使用是完全可以的.在P0896之后,将ranges::copy
与std::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
.
这篇关于为什么range的算法与std的迭代器不兼容?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!