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

Why aren't ranges' algorithms compatible with std's iterators?

本文关键字:迭代器 不兼容 std 范围 算法 为什么      更新时间:2023-10-16
#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 
}

该问题显示在上面的代码中。我使用范围-v3-0.3.7。

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

如果是这样,为什么 range 的算法与 std 的迭代器不兼容?

对我来说

,通用算法copy不应该关心目标迭代器类型,只要它满足输出迭代器的要求。

这是正确的。并不是说ranges::copy以某种方式识别ranges::ostream_iterator而不是std::ostream_iterator.而是 Ranges 对 OutputIterator 有一个精致的概念这样ranges::ostream_iterator可以对 OutputIterator 进行建模,但std::ostream_iterator没有

具体来说,ranges::copy()需要WeaklyIncrementable<O>,这需要细化SemiRegular<O>需要DefaultConstructibleranges::ostream_iterator是默认可构造的,但std::ostream_iterator不是。

因此失败。


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


作为对此的更新,P2325R3 刚刚在 C++20 中追溯采用,这恢复了此更改。std::ostream_iterator将不再是默认可构造的,weakly_incrementable概念将不再需要默认的可构造性(以及其他更改(。


请注意,range-v3/Range TS/Ranges 提案概念 OutputIterator 与标准库现有的 OutputIterator 概念是分开的。std::ostream_iterator不对前者进行建模,但它确实对后者进行建模 - 因此今天使用带有std::ostream_iteratorstd::copy是完全可以的。而在 P0896 之后,使用带有std::ostream_iteratorranges::copy也可以 - 因为提议对std::ostream_iterator进行更改.