C++23 std::generator — 코루틴 기반 시퀀스 생성
std::generator<T>는 C++23에서 도입된 코루틴 기반 범위(range) 생성기입니다. co_yield로 값을 하나씩 생산하고 호출자가 가져갈 때까지 실행을 중단합니다. Python의 yield 생성기와 동일한 개념입니다.
1. 기본 사용
섹션 제목: “1. 기본 사용”#include <generator>#include <iostream>#include <ranges>
std::generator<int> iota(int start = 0){ while (true) co_yield start++;}
int main(){ // 처음 10개만 소비 for (int v : iota(1) | std::views::take(10)) std::cout << v << ' '; // 1 2 3 4 5 6 7 8 9 10}2. 유한 시퀀스
섹션 제목: “2. 유한 시퀀스”#include <generator>#include <vector>
std::generator<int> fibonacci(){ int a = 0, b = 1; while (true) { co_yield a; auto next = a + b; a = b; b = next; }}
std::generator<int> range(int from, int to, int step = 1){ for (int i = from; i < to; i += step) co_yield i;}
// 사용for (int v : range(0, 10, 2)) std::cout << v << ' '; // 0 2 4 6 83. 재귀 generator — co_yield*
섹션 제목: “3. 재귀 generator — co_yield*”co_yield*로 다른 generator의 모든 값을 위임합니다.
#include <generator>
struct TreeNode { int value; TreeNode* left = nullptr; TreeNode* right = nullptr;};
std::generator<int> inorder(TreeNode* node){ if (!node) co_return;
co_yield std::ranges::elements_of(inorder(node->left)); // 왼쪽 서브트리 co_yield node->value; co_yield std::ranges::elements_of(inorder(node->right)); // 오른쪽 서브트리}
// 사용for (int v : inorder(root)) std::cout << v << ' '; // 중위 순회 결과4. ranges 파이프라인과 연동
섹션 제목: “4. ranges 파이프라인과 연동”#include <generator>#include <ranges>#include <algorithm>
std::generator<int> primes(){ auto is_prime = [](int n) { if (n < 2) return false; for (int i = 2; i * i <= n; ++i) if (n % i == 0) return false; return true; };
for (int n = 2; ; ++n) if (is_prime(n)) co_yield n;}
int main(){ // 처음 10개 소수 auto first10 = primes() | std::views::take(10) | std::ranges::to<std::vector>(); // {2, 3, 5, 7, 11, 13, 17, 19, 23, 29}
// 100 이하의 소수 합 int sum = 0; for (int p : primes() | std::views::take_while([](int n){ return n <= 100; })) sum += p;}5. 파일 라인 스트리밍
섹션 제목: “5. 파일 라인 스트리밍”#include <generator>#include <fstream>#include <string>
std::generator<std::string> read_lines(const std::string& path){ std::ifstream file(path); std::string line; while (std::getline(file, line)) co_yield line;}
// 대용량 파일을 메모리에 전부 읽지 않고 처리for (const auto& line : read_lines("large.log") | std::views::filter([](const std::string& l){ return l.contains("ERROR"); })){ process(line);}6. generator vs coroutine 직접 구현
섹션 제목: “6. generator vs coroutine 직접 구현”| 항목 | std::generator | 직접 코루틴 구현 |
|---|---|---|
| 코드 양 | 최소 | 많음 (promise_type 등) |
| 성능 | 최적화됨 | 직접 제어 가능 |
| ranges 호환 | 기본 지원 | 직접 구현 필요 |
| 적합 용도 | 시퀀스 생성 | 복잡한 비동기 흐름 |
7. 컴파일러 지원 현황 (2025년 기준)
섹션 제목: “7. 컴파일러 지원 현황 (2025년 기준)”- GCC 14+: 지원
- Clang 18+: 지원 (
-std=c++23) - MSVC 19.38+: 지원
g++ -std=c++23 -O2 main.cppstd::generator는 지연 평가 시퀀스를 직관적인 코루틴 문법으로 구현합니다. 무한 시퀀스, 트리 순회, 대용량 파일 스트리밍 등 “다음 값을 요청할 때만 계산”하는 패턴에 이상적입니다. std::views와 조합하면 강력한 지연 파이프라인을 간결하게 표현할 수 있습니다.