问题标签 [std-ranges]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
330 浏览

c++ - Range-v3 视图组合和视图计算并行化

取自 range-v3 文档,以下示例演示了一个简单的views流水线组合以生成range

我知道这views::foo相当于类似的东西foo_view(),因此上面的示例最终如下:

现在的问题是:

remove_if和操作的顺序是如何transform发生的?(我知道他们是懒惰的,他们实际上并没有在这一步计算,而不是稍后rng具体化,但这不是重点)。

我可以在这里看到两个选项:

  1. 这些操作由 range-v3融合rng,当通过某个迭代器访问给定的元素时,这两个操作因此应用于该元素。

  2. 当请求给定元素时,整个remove_if操作将被应用vi,然后该操作的输出向量被馈送到transform. 因此,我们最终得到了一个完整的“ trasformed + removed_if ”向量,它使我们能够访问所需的元素。

我很确定选项(1)是实际发生的事情。如果是这样的话,range-v3 是如何做到这一点的呢?它是否具有某种通用组合代码以组合无限数量的按视图组合操作?

附带问题:range-v3 视图公开了什么样的迭代器?我认为random-access迭代器下方的任何内容都会使并行化变得不可能。

range-algorithms元问题:如果选项(1)是事实,那么考虑到它们将一个简单的范围(由多个视图组成,通过操作融合按需计算)作为输入,并行化不是非常简单吗?

0 投票
1 回答
138 浏览

c++ - 为什么 views::reverse 可以将 non-sized_range 转换为 size_range?

[range.sized#1] 中

sized_­range概念对范围进行了细化,要求范围内的元素数量可以在摊销的 常数时间内使用来确定ranges​::​size

该标准规定,保证在恒定时间内获得 的大小。考虑以下:ranges::sized_range

r1显然不是sized_range,因为不可能在常数时间内得到它的大小,这也意味着我们ranges::size用来评估它的大小也是病态的。

但我偶然发现,如果我们应用views::reverse它,新的范围r2突然变成了 a sized_range,我们可以直接使用godboltranges::size来正确获取它的大小:

但是,很明显新范围r2不是 a sized_range,因为我们永远无法在恒定时间内得到它的大小,这似乎违反了标准所说的。

为什么可以views::reverse将非sized_range变成a sized_range?显然,这种转换不会对原始范围的大小产生任何影响。这是标准缺陷还是库错误?

0 投票
1 回答
83 浏览

c++ - 范围的 std::lexicographical_compare_three_way

为什么有std::lexicographical_compare_three_way,但没有std::ranges::lexicographical_compare_three_way

有参数 Comp std::ranges::lexicographical_compare,但它相当没用,因为函数返回bool,当需要比较类别类型之一时。

以下是 cppref 的一些链接
https://en.cppreference.com/w/cpp/algorithm/lexicographical_compare_three_way
https://en.cppreference.com/w/cpp/algorithm/ranges/lexicographical_compare

0 投票
0 回答
140 浏览

c++ - C++20 views::join 在生成的嵌套范围内进入无限循环::single_view

我正在使用具有 GCC 实现(v10.2 和 v11)的 C++20 范围。

为了测试 的行为std::views::join,我尝试使用生成嵌套视图single然后使用.join

[在编译器资源管理器中]

我希望找到一个具有初始值 (1)的for循环迭代器。但是没有......它进入了一个无限循环,因为我使用了这个值,所以它会出现段错误。

std::views::single如果我用std::views::iota(a,b)or替换嵌套std::views::empty<int>,则行为完全可以。

您知道这是否是正确的预期行为(以及为什么)?

编辑

std::ranges::next(v.begin()) == v.end()一定是真的。

这是 GCC 10.3 和 11.1 中的一个错误。
它已在 GCC 主干和 11.1.1 中修复。

0 投票
1 回答
128 浏览

c++ - 在 C++20 视图管道中调用了两次生成器

views在一个简单的适配器管道中,gen调用了一个函数来生成一系列值(使用内部状态),然后对其进行过滤。

令人惊讶和违反直觉的(至少对我而言)是生成器函数在每次迭代中被调用两次,因此对同一过滤器的下一次检查失败(过滤后的值不会在管道中重用)。

您知道这是否是正确的预期行为(以及为什么)?

在 GCC 10.3、11.1libstdc++和中继(代码)和range-v3GCC 和铿锵声(代码)中进行了测试。

注意:如果gen函数被编写为具有内部状态的可变函数,则它不会编译:

(而且我知道纯函数更好)

0 投票
1 回答
1442 浏览

c++ - 在 C++20 中引入的 std::views::all 是什么?

成功编译g++11 -std=c++20。但我无法区分v | std::views::drop(2)和之间的任何区别std::views::all(v) | std::views::drop(2)

所以,我的问题是:

C++20 中引入了什么?std::views::all

0 投票
1 回答
151 浏览

c++ - 如何在自定义容器中支持范围适配器?

我创建了一个名为goldbox仅包含算术类型的自定义容器,并且我还实现beginend成员函数来迭代元素。

我的完整源代码:

输出:

但我想使用范围来使用它,这样我就不必创建新实例。

一旦我应用了goldbox基于范围的 for 循环内部:

它会引发错误,因为我没有提供operator|.

如果我使用非管道语法:

它仍然会抛出一个错误,两者beginend没有在范围内声明。

0 投票
2 回答
155 浏览

c++ - 为什么`std::ranges::clamp`如此严格地限制投影的数量?

根据[alg.clamp#5],时间复杂度std::ranges::clamp最多需要 2 次比较和3次投影应用。cppreference中的可能实现由下式给出:

这显然不符合要求,因为它涉及3个比较和6个投影。即使我们注释掉assert,投影的数量仍然是4,因为std::invoke(proj, v)执行了两次。

我能想到的唯一方法是临时存储 的结果std::invoke(proj, v),然后将其传递给接下来的两个comp调用,就像libstdc++一样:

但是为了安全起见,我们似乎无法在第一次调用std::forward<decltype(__proj_val)>(__proj_val)中完美转发,这意味着我们似乎无法仅使用 3 个投影来完美实现.__proj_valcompstd::ranges::clamp

为什么要std::ranges::clamp如此严格地限制投影数量?这是否意味着需要临时存储投影结果以满足复杂性要求?还是我对这种复杂性要求的理解是错误的?

0 投票
1 回答
88 浏览

c++ - 有没有一种干净的方法来使用范围拆分逗号和空格分隔的单词?

我实际上是根据昨天删除的问题改编这个问题。

输入:一个字符串,包含逗号分隔的单词,逗号后有空格。

输出:单词。

“干净”是指不依赖于根据代码的意图将临时变量存储到没有理由存在的变量中的东西。

我的尝试

基于最小惊讶的原则,我预计像这样的 oneliner 应该可以工作,

但事实并非如此。

0 投票
1 回答
94 浏览

c++ - std::regular_invocable 和按值参数

以下示例是否旨在显示违反先决条件?

std::ranges::transform_view有限制F fun它应该是regular_invocable<F&, range_reference_t<V>>。正如[concept.regularinvocable] regular_invocable中所写“不得修改函数对象或参数”。所以r2函数违反了语义约束,因为它通过移动来修改参数。

这种解释有效吗?