Писал итераторы с кучей boilerplate для ленивого чтения? Или тащил ranges::views для простых генераторов?
C++23 добавляет
std::generator — coroutine-based ленивые последовательности. Пишешь как обычную функцию, получаешь итератор. Идеально для парсеров, ленивого чтения файлов, бесконечных последовательностей.#include <generator>
#include <print>
#include <fstream>
#include <string>
#include <optional>
// Простой генератор чисел Фибоначчи
std::generator<uint64_t> fibonacci(size_t count) {
uint64_t a = 0, b = 1;
for (size_t i = 0; i < count; ++i) {
co_yield a;
auto next = a + b;
a = b;
b = next;
}
}
// Ленивое чтение строк из файла
std::generator<std::string> read_lines(const std::string& filename) {
std::ifstream file(filename);
std::string line;
while (std::getline(file, line)) {
co_yield line;
}
}
// Генератор простых чисел (бесконечный)
std::generator<uint64_t> primes() {
co_yield 2;
std::vector<uint64_t> found_primes;
uint64_t candidate = 3;
while (true) {
bool is_prime = true;
for (auto p : found_primes) {
if (p * p > candidate) break;
if (candidate % p == 0) {
is_prime = false;
break;
}
}
if (is_prime) {
found_primes.push_back(candidate);
co_yield candidate;
}
candidate += 2;
}
}
// Генератор с трансформацией
std::generator<int> squares(int n) {
for (int i = 0; i < n; ++i) {
co_yield i * i;
}
}
void demo() {
// Первые 10 чисел Фибоначчи
std::print("Fibonacci: ");
for (auto num : fibonacci(10)) {
std::print("{} ", num);
}
std::println("");
// Первые 20 простых
std::print("Primes: ");
size_t count = 0;
for (auto prime : primes()) {
std::print("{} ", prime);
if (++count >= 20) break;
}
std::println("");
// Квадраты
std::print("Squares: ");
for (auto sq : squares(5)) {
std::print("{} ", sq);
}
std::println("");
}
❗️ Используй
generator вместо ручного написания итераторов для ленивых последовательностей. Память выделяется только под state coroutine. Можно делать бесконечные последовательности без риска.Библиотека C/C++ разработчика
#под_капотом