Namensräume
Varianten
Aktionen

std::coroutine_handle, std::noop_coroutine_handle

Von cppreference.com
< cpp‎ | coroutine
 
 
Dienstprogramm-Bibliotheken
Sprachunterstützung
Typunterstützung (Basistypen, RTTI)
Bibliotheks-Feature-Test-Makros (C++20)
Programm-Dienstprogramme
Variadische Funktionen
Coroutine-Unterstützung (C++20)
Vertragsunterstützung (C++26)
Drei-Wege-Vergleich
(C++20)
(C++20)(C++20)(C++20)  
(C++20)(C++20)(C++20)

Allgemeine Hilfsmittel
Relationale Operatoren (in C++20 veraltet)
 
Coroutine support
Coroutine traits
Coroutine handle
coroutine_handle
(C++20)
No-op coroutines
Trivial awaitables
Range generators
(C++23)
 
 
Definiert in Header <coroutine>
template< class Promise = void >
struct coroutine_handle;
(1) (seit C++20)
template<>
struct coroutine_handle<void>;
(2) (seit C++20)
template<>
struct coroutine_handle<std::noop_coroutine_promise>;
(3) (seit C++20)
using noop_coroutine_handle =
    std::coroutine_handle<std::noop_coroutine_promise>;
(4) (seit C++20)

Die Klassenschablone coroutine_handle kann verwendet werden, um auf eine pausierte oder ausgeführte Coroutine zu verweisen. Jede Spezialisierung von coroutine_handle ist ein LiteralType.

1) Primäre Schablone, kann aus dem Promise-Objekt vom Typ Promise erstellt werden.
2) Spezialisierung std::coroutine_handle<void> löscht den Promise-Typ. Sie ist von anderen Spezialisierungen konvertierbar.
3) Spezialisierung std::coroutine_handle<std::noop_coroutine_promise> verweist auf No-Op-Coroutinen. Sie kann nicht aus einem Promise-Objekt erstellt werden.

Bei typischen Implementierungen ist jede Spezialisierung von std::coroutine_handle TriviallyCopyable.

Wenn das Programm Spezialisierungen für std::coroutine_handle hinzufügt, ist das Verhalten undefiniert.

Inhalt

[bearbeiten] Datenmember

Member-Name Definition
ptr (private) Ein Zeiger void* auf den Coroutine-Zustand.
((exposition-only member object*)

[bearbeiten] Member-Funktionen

konstruiert ein coroutine_handle-Objekt
(public member function) [bearbeiten]
weist das coroutine_handle-Objekt zu
(public member function) [bearbeiten]
Konversion
ruft ein typ-gelöschtes coroutine_handle ab
(public member function) [bearbeiten]
Observer
prüft, ob die Coroutine abgeschlossen ist
(public member function) [bearbeiten]
prüft, ob der Handle eine Coroutine repräsentiert
(public member function) [bearbeiten]
Steuerung
setzt die Ausführung der Coroutine fort
(public member function) [bearbeiten]
zerstört eine Coroutine
(public member function) [bearbeiten]
Zugriff auf Promise
greift auf das Promise einer Coroutine zu
(public member function) [bearbeiten]
erstellt ein coroutine_handle aus dem Promise-Objekt einer Coroutine
(public static member function) [bearbeiten]
Export/Import
exportiert die zugrundeliegende Adresse, d.h. den Zeiger, der die Coroutine unterstützt
(public member function) [bearbeiten]
importiert eine Coroutine aus einem Zeiger
(public static member function) [bearbeiten]

[bearbeiten] Nicht-Member-Funktionen

vergleicht zwei coroutine_handle-Objekte
(Funktion) [bearbeiten]

[bearbeiten] Hilfsklassen

Hash-Unterstützung für std::coroutine_handle
(Klassentemplate-Spezialisierung) [bearbeiten]

[bearbeiten] Hinweise

Ein coroutine_handle kann verwaist sein, in diesem Fall muss der coroutine_handle vorsichtig verwendet werden, um undefiniertes Verhalten zu vermeiden.

[bearbeiten] Beispiel

#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';
}

Ausgabe

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

[bearbeiten] Fehlerberichte

Die folgenden Verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.

DR angewendet auf Verhalten wie veröffentlicht Korrigiertes Verhalten
LWG 3460 C++20 die öffentliche Basisklasse von coroutine_handle könnte sie in einem unerwünschten Zustand hinterlassen Vererbung entfernt

[bearbeiten] Siehe auch

(C++23)
Eine view, die einen synchronen Coroutine-Generator repräsentiert
(Klassentemplate) [bearbeiten]