【发布时间】:2020-08-07 13:19:16
【问题描述】:
我的意图是使用通用接口来迭代来自各种 I/O 源的文件。例如,我可能想要一个迭代器,在授权允许的情况下,它会延迟打开文件系统上的每个文件并返回打开的文件句柄。然后,我想使用相同的接口来迭代可能来自 AWS S3 存储桶的对象。在后一种情况下,迭代器会将每个对象/文件从 S3 下载到本地文件系统,然后打开该文件,并再次返回文件句柄。显然,两个迭代器接口背后的实现会非常不同。
我认为三个最重要的设计目标是:
- 对于每个
iter++调用,将返回一个std::future 或PPL pplx::task 来表示请求的文件句柄。我需要能够执行 PPLchoice(when_any)的等效操作,因为我希望有多个迭代器同时运行。 - 自定义迭代器实现必须是持久的/可恢复的。也就是说,它会定期记录它在文件系统扫描(或 S3 存储桶扫描等)中的位置,以便在应用程序崩溃并重新启动时尝试从最后一个已知位置恢复扫描。
- 尽最大努力不超越 C++11(可能还有 C++14)。
我假设将 STL input_iterator 作为接口的出发点。毕竟,我看到了这个2014 SO post with a simple example。它不涉及IO,但我看到另一个article from 2001 that allegedly does incorporate IO into a custom STL iterator。到目前为止一切顺利。
当我阅读“Generator functions in C++”之类的文章时,我开始担心。确认!那篇文章给我的印象是,我无法实现创建生成器函数的意图,伪装成迭代器,可能不等待 C++20。同样,另一个2016 SO post 听起来像是用 C++ 创建生成器函数的马蜂窝。
虽然我的自定义迭代器的实现会很复杂,但也许最后两个链接要解决的问题超出了我想要实现的目标。换句话说,也许我的计划没有缺陷?如果我假设在自定义 input_iterator 后面实现惰性生成器,我想知道我正在克服哪些障碍。如果我应该使用其他东西,比如 Boost iterator_facade,我会很感激关于“为什么”的一些解释。另外,我想知道我正在做的事情是否已经在其他地方实施。也许我刚刚开始学习的 PPL 已经有了解决方案?
附言我举了一个 S3 迭代器的例子,它懒惰地下载每个请求的文件,然后返回一个打开的文件句柄。是的,我知道这意味着迭代器正在产生副作用,通常我希望避免这种情况。但是,出于我的预期目的,我不确定是否有更干净的方法来做到这一点。
【问题讨论】:
标签: c++ boost stl generator lazy-evaluation