C++ 协程可以包含普通的“return”语句吗?

cit*_*lao 9 c++ uwp c++-winrt c++-coroutine cppwinrt

我正在使用C++/WinRT为 UWP 控件编写 C++ 协程:

winrt::fire_and_forget MyControl::DoSomething()
{
    if (/* some condition */)
    {
         // Why does this work?!
         return;
    }

    co_await winrt::resume_foreground(Dispatcher());

    // Do some stuff

    co_return;
}

Run Code Online (Sandbox Code Playgroud)

这是为我编译的,但据我所知,C++ 协程不允许简单的return语句。这是编译器中的错误吗?

(有趣的是,我无法将 更改co_returnreturn;我收到编译器错误。是否只能在or之后返回语句?)co_awaitco_yieldco_return

免责声明:我在微软工作。

cit*_*lao 12

这似乎是 MSVSC 的遗留实现。MSVSC 在标准正式完成之前就实现了协程,因此异步有两种实现/async/async:strict)。我似乎打开了旧的、不符合 xe2x80x93 标准的版本。

\n

标准明确规定不能return在协程中使用普通语句(强调是已添加):

\n
\n

协程不能使用可变参数、普通返回语句或占位符返回类型(auto 或 Concept)。Constexpr 函数、构造函数、析构函数和 main 函数不能是协程。

\n
\n

\xe2\x80\x94 https://en.cppreference.com/w/cpp/language/coroutines

\n

您可以通过一个简单的示例( Godbolt 中的视图)来验证这是否是遗留行为:

\n
// ... boilerplate to make std::futures awaitable ...\n// via https://stackoverflow.com/a/70406948/788168\n\nstd::future<int> compute_value()\n{\n    if (rand() > 5)\n    {\n        // Shouldn\'t work:\n        return 5;\n    }\n\n    int result = co_await std::async([] { return 30; });\n\n    co_return result;\n}\n\nint main() {\n    compute_value();\n}\n
Run Code Online (Sandbox Code Playgroud)\n

使用x64 msvc v19.latest编译器和/std:c++20标志,我们得到这个错误:

\n
example.cpp\n<source>(38): error C3773: Use of \'return\' in this context is a non-conforming extension in C++20\n<source>(38): note: Please use \'/await\' command-line option to enable relevant extensions\nCompiler returned: 2\n
Run Code Online (Sandbox Code Playgroud)\n
\n

因此,回答以下问题:

\n
\n

这是为我编译的,但据我所知,C++ 协程不允许简单的return语句。这是编译器中的错误吗?

\n

(有趣的是,我无法将 更改co_returnreturn;我收到编译器错误。是否只能在or之后返回语句?)co_awaitco_yieldco_return

\n
\n

这不是编译器中的错误,它只是一个非标准实现。如果您使用标准实现(使用/async:strict/std:c++20),则该简单return语句将无法编译。符合标准的协程永远不能使用简单的返回语句。

\n