为什么VS2017协程不能返回无效?

Why can't VS2017 coroutines return void?

本文关键字:返回 无效 不能 VS2017 程不能 为什么      更新时间:2023-10-16

我正在对目前在VS2017中实验的C ++协程进行一些实验。我只是想有一个协程,它不返回任何内容,而是在某个协程对象上调用co_await,比方说,在恢复之前在另一个线程上进行一些处理。但是,VS 甚至不会编译返回 void 的最基本的协程程序。例如:

#include "stdafx.h"
#include <experimentalcoroutine>
using namespace std::experimental;
void bob()
{
co_await suspend_always{};
}
int main()
{
bob();
}

导致错误:

1>c:\Program Files (x86)\Microsoft Visual 工作室\2017\专业\VC\工具\msvc\14.10.25017\include\experimental\resumable(46): 错误 C2825:"_Ret":后跟 '::' 1>d:\dev\coroutinestest\main.cpp(10): 注意:请参阅参考 类模板实例化 正在编译的"std::experimental::coroutine_traits" 1>c:\Program Files (x86)\Microsoft Visual 工作室\2017\专业\VC\工具\msvc\14.10.25017\include\experimental\resumable(46): 错误 C2510:"_Ret":"的左侧必须是类/结构/联合 1>c:\Program Files (x86)\Microsoft Visual 工作室\2017\专业\VC\工具\msvc\14.10.25017\include\experimental\resumable(46): 错误 C2061:语法错误:标识符"promise_type"1>c:\program 文件 (x86)\Microsoft Visual 工作室\2017\专业\VC\工具\msvc\14.10.25017\include\experimental\resumable(46): 错误 C2238:在";"之前出现意外令牌

现在我假设这个错误是由于 void::p romise_type 是无意义的,但是为什么当没有什么可返回时甚至实例化 promise 类型?我希望能够从协程中返回任何内容。这只是实现中的当前错误,还是我误解了协程的使用。

谢谢

当然它可以返回void.它没有的原因是 - 没有人为void实现协程协议。您可以自己实现它。返回类型的协程协议通过提供coroutine_traits专用化来满足。

若要使void成为协程的有效返回类型,可以执行以下操作:

namespace std::experimental
{
template<class... T>
struct coroutine_traits<void, T...>
{
struct promise_type
{
void get_return_object() {}
void set_exception(exception_ptr const&) noexcept {}
bool initial_suspend() noexcept
{
return false;
}
bool final_suspend() noexcept
{
return false;
}
void return_void() noexcept {}
};
};
}

这允许您的示例进行编译。

但是,请注意,在您的示例中,调用co_await suspend_always{};会导致内存泄漏,这是因为coroutine_handle很像原始指针,并且您需要自己确保协程被销毁。

作为旁注,协程仿真库 CO2 却做出了另一个决定 - 它的co2::coroutine具有唯一的所有权,因此对CO2_AWAIT(suspend_always{});的调用不会泄漏内存,它只会取消协程。

我在尝试调试编译器错误消息时偶然发现了这个问题。对我来说,解决方案是使函数返回IAsyncAction而不是返回void