【发布时间】:2016-05-14 16:10:08
【问题描述】:
问题
假设我有两个 Iterator 类型的迭代器 begin 和 end 和一些谓词 predicate(存储在 obj 中)。我想实现我可以写的方法some_collection()o
for(auto element: obj.get_collection()) {
do_smth()
}
所以它只适用于满足谓词的元素(即等同于这样的smth)
for (auto element: range(begin, end)) {
if (predicate(element)) {
do_smth();
}
}
我的解决方案
我想到的大致实现如下(伪代码):
struct Wrapper {
op++() {
do {
++value;
while (!predicate(*value));
}
op*() {
return *value;
}
op !=(Iterator other) {
return value != other.value;
}
Iterator value;
}
返回对象的begin() 会是这样的
value = begin;
while (!predicate(*value)) ++value;
return Wrapper(value)
而end() 就是Wrapper(end)
注意事项
我不喜欢这个实现:
- 冗长:我只需要过滤,并且必须编写大量代码
- 初始化有点丑 - 必须在那里增加
- 如果我不迭代所有对象(将破坏或不使用任何值),我将额外迭代(到下一个未使用的元素)
我可以在每次取消引用之前进行迭代(以修复第 2 点和第 3 点),但这会使!= end 检查更加困难(我需要提前减少 end 或在检查本身中使用增量,这意味着在循环)
要求
我没有特定的语言版本要求,甚至对使用尚未批准的实现感兴趣。但 C++11 会是最棒的
我对支持的迭代器类别没有具体要求。我相信我的会与ForwardIterators 合作。
我对代码的可理解性和效率都很感兴趣。
任何更接近银弹的解决方案? :)
【问题讨论】:
-
如果您不想预先计算过滤范围(想到
std::partition()),您的代码似乎足够接近最优。虽然如果你已经担心这个级别的性能......
标签: c++ iterator iteration filtering