std::suspend_never

std::suspend_never (절대 일시 중단하지 않는 awaiter)

코루틴이 절대 일시 중단(suspend)되지 않도록 하는 awaiter 타입이에요. co_await std::suspend_never{}를 쓰면 현재 코루틴이 일시 중단되지 않고 계속 진행돼요. C++20부터 있어요.

출처: cppreference

본문

<coroutine> 헤더에 정의돼 있고, 코루틴을 일시 중단시키지 않는 awaiter예요. 특수화 가능한(open) awaiter 타입으로, co_await 표현식에서 awaiter로 사용되면 코루틴이 절대 일시 중단되지 않아요.

struct suspend_never
{
    constexpr bool await_ready() const noexcept;
    constexpr void await_suspend( std::coroutine_handle<> ) const noexcept;
    constexpr void await_resume() const noexcept;
};
  • await_ready(): true를 돌려줘요. 즉 코루틴을 일시 중단할 필요가 없다고 알려줘요.
  • await_suspend(...): 코루틴이 일시 중단되지 않으므로 호출되지 않아요.
  • await_resume(): 재개 시 반환 값. 아무것도 반환하지 않아요(void).

이 멤버들이 모두 constexpr이므로 co_await를 상수 식 문맥에서도 사용할 수 있어요.

std::suspend_always와 정반대로, 코루틴의 promise 타입에서 initial_suspendfinal_suspendstd::suspend_never{}로 만들면, 각각 "코루틴 생성 즉시 본문 실행"(lazy 호출 대신 eager), "종료 시 다시 중단하지 않고 즉시 소멸"이 되도록 해요. 지연 실행을 하지 않고 곧바로 계산을 수행하는 코루틴에 유용해요.

예제를 보면요.

#include <coroutine>

struct task
{
    struct promise_type
    {
        task get_return_object() { return {}; }
        std::suspend_never initial_suspend() { return {}; } // 시작 시 중단하지 않음
        std::suspend_always final_suspend() noexcept { return {}; }
        void return_void() {}
        void unhandled_exception() {}
    };
};

이렇게 initial_suspendstd::suspend_never로 하면 코루틴을 만들자마자 본문이 즉시 실행되기 시작해요(eager execution).

더 알아보기 (Learn more)

cppreference