std:: coroutine_handle, std:: noop_coroutine_handle
|
Definiert im 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 Klassenvorlage
coroutine_handle
kann verwendet werden, um sich auf eine angehaltene oder ausgeführte Coroutine zu beziehen. Jede Spezialisierung von
coroutine_handle
ist ein
LiteralType
.
Promise
erstellt werden.
In typischen Implementierungen ist jede Spezialisierung von
std::coroutine_handle
ein
TriviallyCopyable
.
Wenn das Programm Spezialisierungen für
std::coroutine_handle
hinzufügt, ist das Verhalten undefiniert.
Inhaltsverzeichnis |
Datenmitglieder
| Mitgliedername | Definition |
ptr
(privat)
|
Ein Zeiger
void
*
auf den Coroutinen-Zustand.
( Nur zur Darstellung verwendetes Mitgliedsobjekt* ) |
Memberfunktionen
konstruiert ein
coroutine_handle
Objekt
(öffentliche Elementfunktion) |
|
weist das
coroutine_handle
Objekt zu
(öffentliche Elementfunktion) |
|
Konvertierung |
|
erhält ein typgelöschtes
coroutine_handle
(öffentliche Elementfunktion) |
|
Beobachter |
|
|
prüft, ob die Coroutine abgeschlossen ist
(öffentliche Elementfunktion) |
|
|
prüft, ob das Handle eine Coroutine repräsentiert
(öffentliche Elementfunktion) |
|
Steuerung |
|
|
setzt die Ausführung der Coroutine fort
(öffentliche Elementfunktion) |
|
|
zerstört eine Coroutine
(öffentliche Elementfunktion) |
|
Promise-Zugriff |
|
|
greift auf das Promise einer Coroutine zu
(öffentliche Elementfunktion) |
|
|
[static]
|
erstellt ein
coroutine_handle
aus dem Promise-Objekt einer Coroutine
(öffentliche statische Elementfunktion) |
Export/Import |
|
|
exportiert die zugrundeliegende Adresse, d.h. den Pointer, der die Coroutine unterstützt
(öffentliche Elementfunktion) |
|
|
[static]
|
importiert eine Coroutine von einem Pointer
(öffentliche statische Elementfunktion) |
Nicht-Member-Funktionen
|
(C++20)
|
vergleicht zwei
coroutine_handle
-Objekte
(Funktion) |
Hilfsklassen
|
Hash-Unterstützung für
std::coroutine_handle
(Klassen-Template-Spezialisierung) |
Hinweise
Ein
coroutine_handle
kann hängend sein, in welchem Fall das
coroutine_handle
mit Vorsicht verwendet werden muss, um undefiniertes Verhalten zu vermeiden.
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 {}; } // Verwendung von co_await in Generator-Coroutinen untersagen. 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; } // Unterstützung für bereichsbasierte for-Schleifen. 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
Fehlerberichte
Die folgenden verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.
| DR | Angewendet auf | Verhalten wie veröffentlicht | Korrektes Verhalten |
|---|---|---|---|
| LWG 3460 | C++20 |
die öffentliche Basisklasse von
coroutine_handle
könnte sie in einem unerwünschten Zustand belassen
|
Vererbung entfernt |
Siehe auch
|
(C++23)
|
Eine
view
, die einen synchronen
Coroutine
-Generator darstellt
(Klassentemplate) |