我已经编写了一个实现类似流的行为的小类(例如,类似std::cin
)。
为了实现元素的"消耗",我增加当前元素,稍后将其与sentinel对象进行比较,以检查流耗尽情况。
最初,我想在实际检索时直接"消耗"(增加)生成的项目。但事实证明,接下来的终止检查已经将最后生成的元素标记为无效。这让我犯了一个错误。
然后,在比较完成后,我转到检查函数中的递增。我发现这是次优的,因为检查通常不会使被检查的东西发生变异。因此,我想问:有没有一种方法可以实现这一点,直接在operator>>()
内部执行递增?
这是代码:
#include <iostream>
template <typename T>
struct Range {
T next, end;
Range(T next, T end) : next(next), end(end) {}
Range& operator>>(T & out) {
out = next++; // <-- intuitively I find it cleanest to increment here
return *this;
}
operator void*() {
return next < end ? this : 0;
}
};
int main() {
Range<int> r(1, 5); // should produce values in [1,5)
int i;
while (r >> i) std::cout << i << 'n';
}
这是输出:
$ g++ test.cc && ./a.out
1
2
3
正如你所看到的,它是关闭了一个。
通过添加额外的变量,这相对容易实现。
这里添加了一个标志,当最后检索到的项有效时该标志为true。那么在operator>>()
中已经可以进行递增和比较。
#include <iostream>
template <typename T>
struct Range {
T next, end;
bool good; // <-- flag that states whether the last retrieved item was valid
Range(T next, T end) : next(next), end(end), good() {}
Range& operator>>(T & out) {
out = next;
good = next++ < end;
return *this;
}
operator void*() {
return good ? this : 0;
}
};
int main() {
Range<int> r(1, 5);
int i;
while (r >> i) std::cout << i << 'n';
}