Visual Studio 2015のCoroutines TS実装に関する質問があります。 P0057r5ワーキングペーパーは、コルーチンは、その本体であるかのように振る舞うことを示す:VS2015 C++コルーチン:promise.get_return_object()戻り値の型とコルーチン戻り値の型
{
P p;
auto gro = p.get_return_object();
co_await p.initial_suspend(); // initial suspend point
F’
final_suspend:
co_await p.final_suspend(); // final suspend point
}
(8.4.4 \ 3条) 、その呼び出し元にコルーチンリターンが、戻り値はによってかのように生成された場合にステートメントreturn gro;
(§8.4.4\ 5)
p.get_return_object()
の結果は、auto
の推論型の変数に格納されます。
コルーチンの戻り値の型をA
およびpromise.get_return_object()
の戻り値の型をB
とします。可変gro
上記P0057r5によれば、(auto
によって推定)タイプB
を有するべきであり、コルーチンは、(例えば、A
にB
からB
または暗黙的なコンストラクタで変換演算子を使用して)、その呼び出し元に戻るときタイプA
の目的はgro
から構成されるべきです。
現在のVisual Studioの実装(コンパイラのバージョン文字列:「x86用のMicrosoft(R)C/C++最適化コンパイラバージョン19.00.24215.1」)で変換がp.initial_suspend()
後に行われるとF'
前gro
型が一致するように設定されたかのように呼び出されますコルーチンの戻り値の型(A
)で、戻り値の型はpromise.get_return_object()
(B
)ではありません。
私に何かが見つからないか、これはバグですか?
最小例(/待機してコンパイル):
#include <experimental/coroutine>
#include <iostream>
struct foo;
struct foo_builder {
foo_builder() {
std::cout << "foo_builder constructor\n";
}
operator foo();
};
struct foo_promise {
foo_builder get_return_object() {
return{};
}
void return_value(int value) {
std::cout << "co_return with " << value << "\n";
}
std::experimental::suspend_never initial_suspend() {
std::cout << "Initial suspend\n";
return{};
}
std::experimental::suspend_never final_suspend() {
return{};
}
};
struct foo {
foo() {
std::cout << "foo constructor\n";
}
using promise_type = foo_promise;
};
foo_builder::operator foo() {
std::cout << "foo_builder conversion to foo\n";
return{};
}
foo coroutine() {
co_return 5;
}
foo simple() {
foo_promise p;
auto gro = p.get_return_object();
// co_await p.initial_suspend(); // initial suspend point
// co_return 5;
p.return_value(5); //S;
goto final_suspend;
final_suspend:
// co_await p.final_suspend(); // final suspend point
return gro;
}
int main() {
auto v = coroutine();
std::cout << "\nregular function:\n";
auto v2 = simple();
std::cin.ignore();
}
出力:auto gro
によってget_return_object()
の戻り値をキャプチャ
Initial suspend
foo_builder constructor
foo_builder conversion to foo
foo constructor
co_return with 5
regular function:
foo_builder constructor
co_return with 5
foo_builder conversion to foo
foo constructor