1

我正在尝试使用 Boost.Range 处理输入序列。该库还有很多不足之处,因此我必须自己编写一些额外的范围适配器。它们中的大多数都很简单,但是当我尝试实现等效于 Haskell 的 groupBy(或 range-v3 的 group_by_view)时,我遇到了一些困难。这是一个转换,它接受一个输入范围并返回一个范围范围,每个范围都包含来自输​​入的一系列相邻元素,这些元素满足某些给定的二元谓词。例如,如果二元谓词是 simple std::equal_to<int>(),则序列

{1, 1, 2, 3, 5, 5, 5, 4, 1}

将映射到

{{1, 1}, {2}, {3}, {5, 5, 5}, {4}, {1}}

我的问题是这个适配器的接口。认为

auto i = (input | grouped_by(std::equal_to<int>())).begin();

如果i递增,则必须扫描底层序列,直到找到 2。但是,如果我首先扫描*i(即 range {1, 1}),我基本上已经找到了第一组的末尾,因此由 引起的遍历++i将是多余的. 可能有一些从内部迭代器到外部迭代器的反馈路径,即i从内部迭代器到达的最后一个元素开始扫描,但这会导致大量开销,并有创建悬空迭代器的风险。

我想知道是否有一些惯用的方法来处理这个问题。理想情况下,重新定义grouped_by界面可以完全回避这个问题。显然,必须扫描输入范围以找到每个组的开头,但我希望有一种可靠的方法来做到这一点,而无需无缘无故地重新扫描元素。(稳健我的意思是只要底层输入范围的迭代器有效,当然不会在扫描期间使迭代器无效。)

那么..有一些已知/经过验证/优雅的解决方案吗?

4

0 回答 0