为什么范围算法与 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
}
该问题显示在上面的代码中。我使用范围-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>
需要DefaultConstructible
。ranges::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_iterator
的std::copy
是完全可以的。而在 P0896 之后,使用带有std::ostream_iterator
的ranges::copy
也可以 - 因为提议对std::ostream_iterator
进行更改.
- 为什么范围算法与 std 的迭代器不兼容?
- forward_list迭代器不兼容
- 向量迭代器不兼容的错误,用于保存另一个向量的迭代器的向量
- C++,弹出调试断言失败窗口,我得到矢量迭代器不兼容的错误运行时
- 当我发生碰撞检测时,矢量迭代器不兼容
- 迭代器不兼容错误
- 字符串迭代器不兼容错误,当我将字符串转换为矢量<byte>时
- 表达式:字符串迭代器不兼容,调用"SetDllDirectory"
- 如何消除"矢量迭代器不兼容"错误?
- 映射/集合迭代器不兼容-检查对象是否在映射中
- 映射/集合迭代器不兼容-检查映射中是否存在键
- 迭代器不兼容的原因
- 矢量迭代器不兼容:DEBUG
- 矢量迭代器不兼容矢量行251
- 矢量迭代器不兼容..但是为什么
- 列出迭代器不兼容断言失败
- C++ STL 向量迭代器不兼容
- 矢量迭代器不兼容:运行时错误
- C++linux获取向量迭代器不兼容
- 获取错误:矢量迭代器不兼容