tgoop.com/cxx95/54
Create:
Last Update:
Last Update:
#madskillz
Итераторы с неопределенным концом 🏁
Итераторы это одна из главных концепций C++. У каждого класса контейнера (set/vector/list/...) в C++ есть свой соответствующий класс итератора (для доступа к своим данным).
Класс, для которого определен итератор, должен иметь методы begin() и end(), по вызову которых отдаются объекты итератора.
Класс итератора должен иметь методы operator++() и operator*().
Наличия этих методов достаточно для использования итератора в разных стандартных методах и в range-based for loop.
Обычно итераторы итерируются по всем объектам от begin() до end():
const std::vector<int> vec{1, 3, 5, 7, 9};
// внизу аналог выражения `for (int value : vec) { /* ... */ }`
auto __begin = vec.begin();
auto __end = vec.end();
for ( ; __begin != __end; ++__begin) {
int value = *__begin;
/* do something with `value`... */
}
Однако бывают случаи, когда end() нельзя вычислить заранее и нужно делать на каждом шагу проверку, не пора ли выходить из цикла. В стандарте C++20 встречается такой костыль:1️⃣ Завести пустой мусорный класс std::default_sentinel_t
2️⃣ Метод
end() класса-"контейнера" должен отдавать объект мусорного класса std::default_sentinel_t end() {
return {};
}
(а метод begin() продолжает отдавать объект итератора)3️⃣ Класс итератора должен определить оператор сравнения с объектом мусорного класса:
bool operator==(std::default_sentinel_t) const {
return /* какое-то условие */;
}
В итоге старый код с итераторами работает как прежде, но завершается только когда оператор сравнения вернет true.Какие есть реально используемые use cases:
🎯 std::counted_iterator - обертка над каким-нибудь другим итератором, итерируется по не более чем
N элементам🎯 Поддержка range-based for для корутин - чтобы можно было в цикле забирать новые значения от корутины, пока она активна (класс итератора -
class Iter)BY C++95
Share with your friend now:
tgoop.com/cxx95/54
