Why aren#39;t ranges#39; algorithms compatible with std#39;s iterators?(为什么范围的算法与 std 的迭代器不兼容?)
问题描述
#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.
如果是这样,为什么范围的算法与 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.
具体来说,ranges::copy()
需要 WeaklyIncrementable<O>
精炼 SemiRegular
需要 DefaultConstructible
.范围::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).
作为对此的更新,P2325R3 刚刚被 C++20 追溯采用,它恢复了这一变化.std::ostream_iterator
将不再是默认可构造的,并且 weakly_incrementable
概念将不再需要默认构造(以及其他更改).
As an update to this, P2325R3 was just adopted retroactively for C++20, which reverts this change. std::ostream_iterator
will no longer be default constructible and the weakly_incrementable
concept will no longer require default constructibility (among other changes).
† 请注意,range-v3/Ranges TS/Ranges Proposal 概念 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
.
这篇关于为什么范围的算法与 std 的迭代器不兼容?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:为什么范围的算法与 std 的迭代器不兼容?
基础教程推荐
- 设计字符串本地化的最佳方法 2022-01-01
- C++ 标准:取消引用 NULL 指针以获取引用? 2021-01-01
- 如何定义双括号/双迭代器运算符,类似于向量的向量? 2022-01-01
- C++ 程序在执行 std::string 分配时总是崩溃 2022-01-01
- 调用std::Package_TASK::Get_Future()时可能出现争用情况 2022-12-17
- 运算符重载的基本规则和习语是什么? 2022-10-31
- 什么是T&&(双与号)在 C++11 中是什么意思? 2022-11-04
- C++,'if' 表达式中的变量声明 2021-01-01
- 如何在 C++ 中处理或避免堆栈溢出 2022-01-01
- 您如何将 CreateThread 用于属于类成员的函数? 2021-01-01