co_yield
- C++ kursu
- İleri seviye
- Ders 70/83
- 5 dk
co_yield ile değer üretmeyi öğrenirsin.
co_yield nedir?
co_yield, bir coroutine'in değer üretip askıya alınmasını sağlar. Her co_yield v; ifadesi, v değerini dışarı verir ve coroutine'i durdurur. Dışarıdan resume() çağrılınca coroutine kaldığı yerden sürer.
Bu, bir üreteç (generator) yazmanın temelidir. Promise türünün yield_value(v) üyesi olmalıdır. Örnek: co_yield 1; co_yield 2;. İlk resume 1 verir, ikinci resume 2 verir. Böylece sonsuz ya da tembel (lazy) dizileri tek fonksiyonla yazabilirsin.
Generator promise
Bir Generator türü, yield_value üyesi olan bir promise_type içerir. Her co_yield v;, yield_value(v) üyesini çağırır ve değer saklanır.
Örnek: std::suspend_always yield_value(int v) { value_ = v; return {}; }. suspend_always döndüğü için coroutine askıya alınır. initial_suspend de suspend_always dönerse, coroutine ilk resume'e kadar başlamaz. Böylece değer, talep oldukça (lazy) üretilir. handle.resume() ile bir sonraki yield'e geçilir; handle.promise().value_ ile değer okunur.
Uygulama co_yield ile sayı üret
counter coroutine'inin gövdesine co_yield 1; ve co_yield 2; yaz. main içindeki resume ve std::cout çağrıları hazırdır; dokunma.
Başlangıç kodu
#include <iostream>
#include <coroutine>
struct Generator {
struct promise_type {
int value_;
Generator get_return_object() { return {std::coroutine_handle<promise_type>::from_promise(*this)}; }
std::suspend_always initial_suspend() { return {}; }
std::suspend_always final_suspend() noexcept { return {}; }
std::suspend_always yield_value(int v) { value_ = v; return {}; }
void return_void() { }
void unhandled_exception() { }
};
std::coroutine_handle<promise_type> handle;
};
Generator counter() {
// co_yield ile 1 ve 2 üret
}
int main() {
auto g = counter();
g.handle.resume();
std::cout << g.handle.promise().value_;
g.handle.resume();
std::cout << g.handle.promise().value_;
return 0;
}Örnek çözüm
#include <iostream>
#include <coroutine>
struct Generator {
struct promise_type {
int value_;
Generator get_return_object() { return {std::coroutine_handle<promise_type>::from_promise(*this)}; }
std::suspend_always initial_suspend() { return {}; }
std::suspend_always final_suspend() noexcept { return {}; }
std::suspend_always yield_value(int v) { value_ = v; return {}; }
void return_void() { }
void unhandled_exception() { }
};
std::coroutine_handle<promise_type> handle;
};
Generator counter() {
co_yield 1;
co_yield 2;
}
int main() {
auto g = counter();
g.handle.resume();
std::cout << g.handle.promise().value_;
g.handle.resume();
std::cout << g.handle.promise().value_;
return 0;
}Beklenen çıktı
12
Soru ve cevaplar
Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.
1 co_yield ne yapar?
- Coroutine'i tamamen bitirir
- Coroutine'i yeniden başlatır
- Bir hata fırlatır
- Bir değer üretir ve coroutine'i askıya alır Doğru cevap
Açıklama: co_yield, değer üretir ve coroutine'i askıya alır; resume ile devam edilir.
2 co_yield değeri
Generator counter() { ____ 1; }
Generator counter() { co_yield 1; }
Açıklama: co_yield 1; değeri üretir ve askıya alır.
3 Üyeyi rolüne eşle
| Kavram | Anlamı |
|---|---|
yield_value |
Değeri saklar |
initial_suspend |
Başlangıç davranışı |
final_suspend |
Bitiş davranışı |
resume() |
Devam ettirir |