suspend_always yield_value(yielded val) noexcept; // (1)
auto yield_value(const remove_reference_t<yielded>& lval)
requires is_rvalue_reference_v<yielded> &&
constructible_from<remove_cvref_t<yielded>, const remove_reference_t<yielded>&>; // (2)
template<class T2, class V2, class Alloc2, class Unused>
requires same_as<typename generator<T2, V2, Alloc2>::yielded, yielded>
auto yield_value(ranges::elements_of<generator<T2, V2, Alloc2>&&, Unused> g) noexcept; // (3)
template<class T2, class V2, class Alloc2, class Unused>
requires same_as<typename generator<T2, V2, Alloc2>::yielded, yielded>
auto yield_value(ranges::elements_of<generator<T2, V2, Alloc2>&, Unused> g) noexcept; // (4)
template<ranges::input_range Rng, class Alloc>
requires convertible_to<ranges::range_reference_t<Rng>, yielded>
auto yield_value(ranges::elements_of<Rng, Alloc> r); // (5)
概要
ジェネレータコルーチンにおけるco_yield式の動作を制御する。 プログラマが本関数を直接利用することは想定されていない。
事前条件
- (2) : Promiseオブジェクトが
*thisとなるコルーチンへのハンドルが、あるgeneratorオブジェクトxのアクティブスタックx.active_のトップにあること。 - (3), (4) : Promiseオブジェクトが
*thisとなるコルーチンへのハンドルが、あるgeneratorオブジェクトxのアクティブスタックx.active_のトップにあること。ジェネレータg.rangeに対応するコルーチンが、初期サスペンドポイントにて中断されていること。 - (5) : Promiseオブジェクトが
*thisとなるコルーチンへのハンドルが、あるgeneratorオブジェクトxのアクティブスタックx.active_のトップにあること。ジェネレータg.rangeに対応するコルーチンが、初期サスペンドポイントにて中断されていること。
効果
(1) : 以下と等価
(5) : 以下と等価
auto nested = [](allocator_arg_t, Alloc, ranges::iterator_t<Rng> i,
ranges::sentinel_t<Rng> s)
-> generator<yielded, void, Alloc> {
for (; i != s; ++i) {
co_yield static_cast<yielded>(*i);
}
};
return yield_value(ranges::elements_of(nested(
allocator_arg, r.allocator, ranges::begin(r.range), ranges::end(r.range))));
戻り値
- (1) :
suspend_always{} - (2) : 以下の動作をする未規定の型のAwaitableオブジェクト
lvalで直接非リスト初期化されたremove_cvref_t<yielded>型オブジェクトを保持する。- 説明専用メンバ
value_が保持オブジェクトを指してコルーチンを中断(suspend)するメンバ関数を持つ。
- (3), (4) : 以下の動作をする未規定の型のAwaitableオブジェクト
- Range
g.rangeの所有権を受け取る。 - メンバ関数
await_ready:falseを返す。 - メンバ関数
await_suspend:xのアクティブスタック*x.active_にg.range.coroutine_をpushしてからg.range.coroutine_を再開(resume)する。 - メンバ関数
await_resume: 説明専用メンバexcept_が例外を保持している場合にrethrow_exception(except_)を行う。そうでなければ、何もしない。
- Range
例外
備考
ジェネレータコルーチンのco_yield式はvoid型となる。
バージョン
言語
- C++23
処理系
- Clang: ??
- GCC: ??
- Visual C++: ??
関連項目
参照
- LWG Issue 3894.
generator::promise_type::yield_value(ranges::elements_of<Rng, Alloc>)should not benoexcept- C++26で、(5)から
noexceptが削除された(効果内で例外を送出しうるgeneratorの構築を行うため)
- C++26で、(5)から
- LWG Issue 3899.
co_yielding elements of an lvalue generator is unnecessarily inefficient- C++26で、左辺値参照をとるオーバーロード(4)を追加し、左辺値
generatorの要素をco_yieldする際の非効率性を解消する
- C++26で、左辺値参照をとるオーバーロード(4)を追加し、左辺値
- LWG Issue 4119.
generator::promise_type::yield_value(ranges::elements_of<R, Alloc>)'s nestedgeneratormay be ill-formed- C++26で、ネストした
generatorの型をgenerator<yielded, void, Alloc>とすることで、generatorのValue型として不適格になる問題を回避する
- C++26で、ネストした