【问题标题】:Is this correct: std::views::reverse on infinite range?这是正确的:无限范围内的 std::views::reverse 吗?
【发布时间】:2021-12-29 15:12:28
【问题描述】:

见这个例子code:

#include <ranges>

int main() {
    for(auto i : std::ranges::iota_view(1) | std::views::reverse) 
        break;
}

它在 gcc 上编译(我无法检查 clang/msvc - 因为它们不支持范围)。 当然——它“永远”运行并且什么都不做。

我还检查了在无限范围内执行 std::ranges::rbegin(inf)std::ranges::rend(inf) 是不允许的(它不会编译)。

我不确定这是否是正确的 c++ 代码? 而且我对 std::ranges::reverse 实现很好奇——看起来 rbegin/rend 不用于实现这个视图——那么这个实现是如何工作的?

【问题讨论】:

    标签: c++ g++ language-lawyer c++20 std-ranges


    【解决方案1】:

    根据[iterator.requirements.general-10]

    一个哨兵s被称为可达一个迭代器i当且仅当 表达式++i 有一个有限的应用序列 使i == s。如果从i 可以访问s,则[i, s) 表示有效范围

    还有[iterator.requirements.general-12]

    将库函数应用于无效范围的结果 未定义。

    由于ranges::iota_view(1) 不是有效范围,因此将views::reverse 应用于它是未定义的行为。

    【讨论】:

    • 因此,并非标准库中的所有范围都对每个定义都有效。有趣的想法。从已删除的@Artyer 答案中,我读到ranges::next(ranges::begin(base_), ranges::end(base_)) 用于使用哨兵结束迭代器实现范围的反向。问题:是否可以通过要求不允许“将库函数应用于无效范围”(即不会编译)而不只是说“未定义”来改进 c++ std?
    • @PiotrNycz。那是一种改进。但是目前的标准确实没有有所谓的“无限范围”(只有range-v3有),因为它与“传统”容器有很大不同,不适合标准算法,所以引入“无限范围”的概念需要一篇论文,这也是目前标准只将其定义为未定义行为的原因。
    猜你喜欢
    • 1970-01-01
    • 2021-08-16
    • 2021-11-18
    • 1970-01-01
    • 2021-08-20
    • 2021-01-05
    • 1970-01-01
    • 2014-04-20
    • 1970-01-01
    相关资源
    最近更新 更多