名稱空間
變體
操作

std::coroutine_handle, std::noop_coroutine_handle

來自 cppreference.com
< cpp‎ | 協程
 
 
 
協程支援
協程特質
協程控制代碼
coroutine_handle
(C++20)
無操作協程
平凡可等待物件
範圍生成器 (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> 擦除 promise 型別。它可以從其他特化轉換。
3) 特化 std::coroutine_handle<std::noop_coroutine_promise> 引用空操作協程。它不能從 promise 物件建立。

在典型的實現中,std::coroutine_handle 的每個特化都是 可平凡複製 (TriviallyCopyable) 的。

如果程式為 std::coroutine_handle 新增特化,則行為是未定義的。

目錄

[編輯] 資料成員

成員名稱 (Member name) 定義
ptr (私有) 指向協程狀態的 void* 指標。
(僅用於闡釋的成員物件*)

[編輯] 成員函式

構造一個 coroutine_handle 物件
(公共成員函式) [編輯]
賦值 coroutine_handle 物件
(公共成員函式) [編輯]
轉換
獲取一個型別擦除的 coroutine_handle
(公共成員函式) [編輯]
觀察器
檢查協程是否已完成
(公共成員函式) [編輯]
檢查控制代碼是否表示一個協程
(公共成員函式) [編輯]
控制
恢復協程的執行
(公共成員函式) [編輯]
銷燬一個協程
(公共成員函式) [編輯]
Promise 訪問
訪問協程的 promise
(公共成員函式) [編輯]
從協程的 promise 物件建立一個 coroutine_handle
(公共靜態成員函式) [編輯]
匯出/匯入
匯出底層地址,即支援協程的指標
(公共成員函式) [編輯]
從指標匯入一個協程
(公共靜態成員函式) [編輯]

[編輯] 非成員函式

比較兩個 coroutine_handle 物件
(函式) [編輯]

[編輯] 輔助類

std::coroutine_handle 的雜湊支援
(類模板特化) [編輯]

[編輯] 註解

一個 coroutine_handle 可能是懸空的,在這種情況下必須小心使用 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 {};
        }
        // Disallow co_await in generator coroutines.
        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;
    }
 
    // Range-based for loop support.
    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.done();
        }
 
        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++ 標準。

缺陷報告 應用於 釋出時的行為 正確的行為
LWG 3460 C++20 coroutine_handle 的公共基類可能使其處於不希望的狀態 繼承被移除

[編輯] 參閱

(C++23)
表示同步協程生成器的view
(類模板) [編輯]