C++ Iterator
Brief
假如需要讓 A
可以被 for(auto ?: A)
使用, 就需要讓以下 code 是可以編譯的:
cpp
for (auto x = A.begin(); x != A.end(); ++x) {
}
所以我們會需要實做:
cpp
struct A {
// A's implements' detail
struct Iter {
Iter& operator++();
bool operator(const Iter& rhs) const;
};
Iter begin();
Iter end();
};
Example
cpp
#include <iostream>
struct Range {
// [l, r)
int l = 0;
int r = 100;
struct Iter {
int ptr = 0;
int& operator*() {
return ptr;
}
Iter& operator++() {
++ptr;
return *this;
}
bool operator!=(const Iter& rhs) {
return ptr != rhs.ptr;
}
};
Iter begin() {
return Iter{l};
}
Iter end() {
return Iter{r};
}
};
int main() {
for (int i: Range()) {
std::cout << i << std::endl;
}
return 0;
}
End 回傳的 ... 可以不同型別?
在某些情況下,我們沒辦法決定 Iter 之間是否相等,只能知道他是否已經結束了,例如 c++23 會出現的 std::generator 就用這個方式。
cpp
struct Iter {
// ...
// 直接判斷 Iter{nullptr} 有點髒,我去翻了一下網路上,看起來會去使用:
// std::default_sentinel_t, 所以用了一樣的方式。
// 這樣子 != 語意上就直接變成 “是不是結束”
bool operator!=(const IterEnd &rhs) const {
return !handle_.done();
}
};
Iter begin() {
return Iter{...};
}
IterEnd end() {
return {};
}