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

Can C++ coroutines contain plain `return` statements?

我正在使用 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;
}

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

(有趣的是,我无法将 co_return 更改为 return;我收到编译器错误。是否只有 return 语句 after一个co_awaitco_yield必须是co_return?)

这似乎是 MSVSC 的遗留实现。 MSVSC 在标准正式完成之前就实现了协程,因此 there are two implementations of async/async/async:strict)。我似乎打开了旧的、不符合标准的版本。

标准很明确,你不能在协程中使用普通的 return 语句(强调已添加):

Coroutines cannot use variadic arguments, plain return statements, or placeholder return types (auto or Concept). Constexpr functions, constructors, destructors, and the main function cannot be coroutines.

https://en.cppreference.com/w/cpp/language/coroutines

您可以通过一个简单的例子来验证这是一个遗留行为 (view in Godbolt):

// ... boilerplate to make std::futures awaitable ...
// via 

std::future<int> compute_value()
{
    if (rand() > 5)
    {
        // Shouldn't work:
        return 5;
    }

    int result = co_await std::async([] { return 30; });

    co_return result;
}

int main() {
    compute_value();
}

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

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

所以,回答问题:

This is compiling for me, but as far as I know, C++ coroutines do not allow plain return statements. Is this a bug in the compiler?

(Interestingly, I cannot change the co_return to return; I get a compiler error. Is it that only return statements after a co_await or co_yield must be co_return?)

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