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

xml*_*lmx 11 c++ iterator c++-concepts range-v3 c++20

#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 
}
Run Code Online (Sandbox Code Playgroud)

问题显示在上面的代码中.我使用range-v3-0.3.7.

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

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

Bar*_*rry 19

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

这是对的.它不是以ranges::copy某种方式识别ranges::ostream_iterator而不是std::ostream_iterator.这就是Ranges对OutputIterator 有一个精致的概念,比如ranges::ostream_iteratorOutputIterator模型,但std::ostream_iterator 没有.

具体而言,ranges::copy()需要WeaklyIncrementable<O>精炼SemiRegular<O>所需的DefaultConstructible.ranges::ostream_iterator是默认的可构造的,但std::ostream_iterator不是.

因此失败了.


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


请注意,range-v3/Ranges TS/Ranges Proposal概念OutputIterator与标准库现有的OutputIterator概念是分开的.std::ostream_iterator不模型前,但它确实模型是后者-所以使用std::copystd::ostream_iterator今天是完全没有问题.并且在P0896后,使用ranges::copya std::ostream_iterator也将没问题 - 因为建议的更改std::ostream_iterator.

  • @Barry:很奇怪;我只是在一个[单独的问题](/sf/ask/3925969631/)中询问了此问题。 (2认同)