생성기(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같은 이름으로 종잇장 넘기듯 값을 순회하고 싶을 때 쓰면 된다.

한 마디 정리

쉽게 규칙에 맞는 값들을 만들어 내는 요술 함수

Back

Comments

No comments yet.