생성기(Generator) 함수에 대하여
by
gg582 · 2026-07-15 07:02:30 · 43 views
소개
std::generator, 즉 생성기는 C++23부터 도입된 문법이다. 이 문법은 일정한 규칙을 가지고 값을 생성하고 순회할 수 있게 돕는다.
물론 이 함수는 이전 시간에 다룬 라이너 그림의 C++20 예제에도 소개되어 있었으나, 아직 std 모듈에 표준 생성기가 도입되어 있지 않았기 때문에 해당 자료의 소스를 참고하여 코드를 새로 작성하였다.
여기서의 예제는 다음 수를 생성하는 예제이며, 값을 양보하는 co_yield 문법을 통해 값을 획득한다.
생성기 함수
std::generator<int> getNext(int limit, int start, int step) {
auto value = start;
for (int i = 0; i < limit; ++i) {
co_yield value;
value += step;
}
}
이곳에서 값의 양보가 일어나는 시점은 반복문에 진입한 직후이며, 양보가 이뤄진 후에 함수 내의 값은 스텝만큼 증가한다.
예시로 이것에 한계값, 시작값, 스텝을 설정하고 보자.
- 한계값: 5, 시작값: 0, 발걸음(step): 1
이렇다고 할 때에, 각 getNext 단계가 첫 번째부터 다섯 번째까지 어떻게 되는지 보자.
| 호출 순서 | value | 더해진 발걸음 |
|---|---|---|
| 1 | 0 | 0×step |
| 2 | 1 | 1×step |
| 3 | 2 | 2×step |
| 4 | 3 | 3×step |
| 5 | 4 | 4×step |
그렇다면, 만약 발걸음 값이 2로 변경되면 어떨까?
한계값이 5이고, 시작값이 0이라고 할 때에, 그 결과는 아래와 같다.
| step = 1 | step = 2 |
|---|---|
| 0 | 0×2 = 0 |
| 1 | 1×2 = 2 |
| 2 | 2×2 = 4 |
| 3 | 3×2 = 6 |
| 4 | 4×2 = 8 |
이것을 실험하기 위한 main 함수를 작성한다.
int main() {
int limit = 5, start = 0, step = 1;
std::cout << "한계값: ";
std::cin >> limit;
std::cout << "시작값: ";
std::cin >> start;
std::cout << "스텝: ";
std::cin >> step;
for (int value : getNext(limit, start, step)) {
std::cout << "Yield " << value << std::endl;
}
return 0;
}
위 함수에서 getNext르르 사용하는 부분을 보면, 마치 벡터의 요소들을 인덱싱할 때처럼 콜론(:)을 사용한다.
이것을 기억해 두면 복잡한 규칙 역시 생성기로 정의해 만들어 올 수 있다.
Makefile
CXX ?= g++
CXXFLAGS = -std=c++23 -fmodules
TARGET = main
SRC = main.cpp
STD_MODULE = $(wildcard /usr/include/c++/$(shell $(CXX) -dumpversion)/bits/std.cc)
all: $(TARGET)
$(TARGET): $(SRC) gcm.cache/std.gcm
$(CXX) $(CXXFLAGS) -o $@ $<
gcm.cache/std.gcm: $(STD_MODULE)
@mkdir -p gcm.cache
$(CXX) $(CXXFLAGS) -c $< -o gcm.cache/std.o
clean:
rm -f $(TARGET)
rm -rf gcm.cache
.PHONY: all clean
실측
아까의 가설이 맞는지 빌드해서 살펴 보자.
소스 내용은 main.cpp에 작성한 후, 쉘에서 make를 명령한다.
이후, 실행해 보면 아래와 같은 결과가 나온다.
yjlee@fedora:~/learn-cpp/생성기$ ./main
한계값: 5
시작값: 0
스텝: 1
Yield 0
Yield 1
Yield 2
Yield 3
Yield 4
yjlee@fedora:~/learn-cpp/생성기$ ./main
한계값: 5
시작값: 0
스텝: 2
Yield 0
Yield 2
Yield 4
Yield 6
Yield 8
yjlee@fedora:~/learn-cpp/생성기$ ./main
한계값: 5
시작값: 1
스텝: 1
Yield 1
Yield 2
Yield 3
Yield 4
Yield 5
yjlee@fedora:~/learn-cpp/생성기$ ./main
한계값: 5
시작값: 1
스텝: 2
Yield 1
Yield 3
Yield 5
Yield 7
Yield 9
yjlee@fedora:~/learn-cpp/생성기$
Step에 따라 양도값이 달라지는 것의 1번, 2번 경우 역시 우리의 예상과 동일하게 나왔다. 그리고 시작값을 1로 변경하였을 때, 값이 1씩 밀려 나오는 것 역시 잘 동작한다.
기본적으로 생성기 함수는 그 때마다 반복문을 어거지로 박아 두기 싫고, getNext, seekNext같은 이름으로 종잇장 넘기듯 값을 순회하고 싶을 때 쓰면 된다.
한 마디 정리
쉽게 규칙에 맞는 값들을 만들어 내는 요술 함수