c++之为什么范围不能用于管道库功能

TianFang 阅读:18 2024-11-24 20:56:43 评论:0

Jonathan Boccara(Fluent C++ 的作者)编写了一个名为 pipes 的库。 .

这个“管道”,存储库的主页说,不像范围的使用,即使它看起来一样:它不是基于懒惰的拉动,而是基于急切的插入。但它是stated不能使用范围库来执行各种“管道”操作。例如:

  • unzip - 采用压缩输入 - 本质上是一系列 k 元组 - 并产生 k 个单独的、独立的输出。
  • fork - 生成容器/范围的多个(独立)拷贝。

  • 我不太明白为什么原则上是这样。 (当然,除了无法获得结束迭代器/哨兵的范围。)

    请您参考如下方法:

    正在讨论的本质上是基于推送的处理方法和基于拉的处理方法之间的区别。在像这个管道库这样的推送系统中,您建立了一个处理链,每个处理步骤都将其数据直接推送到下一个处理步骤。在像范围这样的拉式系统中,您可以建立数据的表示,您可以根据需要访问和修改它。处理不会自行发生;只有当有人试图消耗范围时才会发生这种情况。
    unzipfork操作都是一对多操作:它们接受单个输入并将其映射到许多处理操作。

    作为一个推送系统,管道库由于其 API 的结构可以处理一对多的操作。一个操作由一个函数调用表示;输入由使用点暗示(使用 >>= 或将其传递给处理器)。函数的参数定义了它的输出(忽略处理器本身的参数)。由于 C++ 函数可以有任意数量的参数,一对多的映射操作自然会失败。您只需为各种输出提供合适的处理器。

    作为拉式系统,范围基于返回值。 C++ 没有返回多个值的语言机制,所以我们能做的最好的事情就是返回一个代表多个值的“值”。

    但是,范围适配器链接最终是基于范围的输入。而“代表多个值的‘值’”本身并不是一个范围。它可能包含范围,但这并不使它成为范围。

    因此,现在您必须采用这种绝对“非范围”的类型,并使您的所有范围适配器都能使用它。应用范围适配器必须在整个类型中广播该操作,从而创建多对多操作。做到这一点并不容易。

    但更重要的是......这可能不是你想要的。如果您 fork一个范围,那么您几乎肯定要对复制的范围进行不同的处理。这完全关闭了使用 | 的任何机会。操作来做到这一点。您必须构建将适配器应用于这些范围元组的特定部分的方法。这些方式越来越像基于推送的处理器。

    归根结底,拉式系统在每个级别只有一个输出。这只是此类 API 核心概念的一部分:每个处理步骤生成 范围。这有其优点(延迟处理),但表示一对多操作是其弱点之一。

    范围当然可以有 unzip函数( fork 实际上只是复制范围)。但它不会是 |样式适配器;这将是一个函数,它接受某个可分解类型的范围并返回一个范围元组。如果您想对它们进行更多处理,则需要将元组存储在一个值中,访问各个元素,并根据需要使用它们。


    标签:C++
    声明

    1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

    关注我们

    一个IT知识分享的公众号