Namespaces
Variants

std:: coroutine_handle, std:: noop_coroutine_handle

From cppreference.net
Utilities library
Coroutine support
Coroutine traits
Coroutine handle
coroutine_handle
(C++20)
No-op coroutines
Trivial awaitables
Range generators
(C++23)
헤더 파일에 정의됨 <coroutine>
template < class Promise = void >
struct coroutine_handle ;
(1) (C++20부터)
template <>
struct coroutine_handle < void > ;
(2) (C++20부터)
template <>
struct coroutine_handle < std:: noop_coroutine_promise > ;
(3) (C++20부터)
using noop_coroutine_handle =
std :: coroutine_handle < std:: noop_coroutine_promise > ;
(4) (C++20부터)

클래스 템플릿 coroutine_handle 는 일시 중단되었거나 실행 중인 코루틴을 참조하는 데 사용할 수 있습니다. coroutine_handle 의 모든 특수화는 LiteralType 입니다.

1) 기본 템플릿, Promise 타입의 promise 객체로부터 생성될 수 있습니다.
2) 특수화 std :: coroutine_handle < void > 는 프로미스 타입을 지웁니다. 다른 특수화들로부터 변환 가능합니다.
3) 특수화 std :: coroutine_handle < std:: noop_coroutine_promise > 는 no-op 코루틴을 참조합니다. 이는 promise 객체로부터 생성할 수 없습니다.

일반적인 구현에서, std::coroutine_handle 의 모든 특수화는 TriviallyCopyable 입니다.

프로그램이 std::coroutine_handle 에 대한 특수화를 추가하는 경우, 동작은 정의되지 않습니다.

목차

데이터 멤버

멤버 이름 정의
ptr (private) 코루틴 상태에 대한 void * 포인터.
( 설명 전용 멤버 객체* )

멤버 함수

coroutine_handle 객체를 생성합니다
(public member function)
coroutine_handle 객체를 할당합니다
(public member function)
변환
타입 삭제된 coroutine_handle 을 얻습니다
(public member function)
관찰자
코루틴이 완료되었는지 확인합니다
(public member function)
핸들이 코루틴을 나타내는지 확인합니다
(public member function)
제어
코루틴의 실행을 재개합니다
(public member function)
코루틴을 파괴합니다
(public member function)
Promise 접근
코루틴의 promise에 접근합니다
(public member function)
코루틴의 promise 객체로부터 coroutine_handle 을 생성합니다
(public static member function)
내보내기/가져오기
기본 주소(즉, 코루틴을 지원하는 포인터)를 내보냅니다
(public member function)
포인터로부터 코루틴을 가져옵니다
(public static member function)

비멤버 함수

coroutine_handle 객체를 비교합니다
(함수)

헬퍼 클래스

std::coroutine_handle 에 대한 해시 지원
(클래스 템플릿 특수화)

참고 사항

A coroutine_handle 는 댕글링(dangling) 상태일 수 있으며, 이 경우 coroutine_handle 을 정의되지 않은 동작을 피하기 위해 신중하게 사용해야 합니다.

예제

#include <coroutine>
#include <iostream>
#include <optional>
template<std::movable T>
class Generator
{
public:
    struct promise_type
    {
        Generator<T> get_return_object()
        {
            return Generator{Handle::from_promise(*this)};
        }
        static std::suspend_always initial_suspend() noexcept
        {
            return {};
        }
        static std::suspend_always final_suspend() noexcept
        {
            return {};
        }
        std::suspend_always yield_value(T value) noexcept
        {
            current_value = std::move(value);
            return {};
        }
        // 제너레이터 코루틴에서 co_await 사용을 금지합니다.
        void await_transform() = delete;
        [[noreturn]]
        static void unhandled_exception() { throw; }
        std::optional<T> current_value;
    };
    using Handle = std::coroutine_handle<promise_type>;
    explicit Generator(const Handle coroutine) :
        m_coroutine{coroutine}
    {}
    Generator() = default;
    ~Generator()
    {
        if (m_coroutine)
            m_coroutine.destroy();
    }
    Generator(const Generator&) = delete;
    Generator& operator=(const Generator&) = delete;
    Generator(Generator&& other) noexcept :
        m_coroutine{other.m_coroutine}
    {
        other.m_coroutine = {};
    }
    Generator& operator=(Generator&& other) noexcept
    {
        if (this != &other)
        {
            if (m_coroutine)
                m_coroutine.destroy();
            m_coroutine = other.m_coroutine;
            other.m_coroutine = {};
        }
        return *this;
    }
    // 범위 기반 for 루프 지원.
    class Iter
    {
    public:
        void operator++()
        {
            m_coroutine.resume();
        }
        const T& operator*() const
        {
            return *m_coroutine.promise().current_value;
        }
        bool operator==(std::default_sentinel_t) const
        {
            return !m_coroutine || m_coroutine.완료();
        }
        explicit Iter(const Handle coroutine) :
            m_coroutine{coroutine}
        {}
    private:
        Handle m_coroutine;
    };
    Iter begin()
    {
        if (m_coroutine)
            m_coroutine.resume();
        return Iter{m_coroutine};
    }
    std::default_sentinel_t end() { return {}; }
private:
    Handle m_coroutine;
};
template<std::integral T>
Generator<T> range(T first, const T last)
{
    while (first < last)
        co_yield first++;
}
int main()
{
    for (const char i : range(65, 91))
        std::cout << i << ' ';
    std::cout << '\n';
}

출력:

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

결함 보고서

다음의 동작 변경 결함 보고서들은 이전에 발표된 C++ 표준에 소급 적용되었습니다.

DR 적용 대상 게시된 동작 올바른 동작
LWG 3460 C++20 coroutine_handle 의 public base class가 원치 않는 상태로 남을 수 있었음 상속 제거됨

참고 항목

(C++23)
동기식 view 코루틴 제너레이터를 나타내는
(클래스 템플릿)