gpt4 book ai didi

c++ - 为什么 VS2017 协程不能返回 void?

转载 作者:搜寻专家 更新时间:2023-10-31 00:55:03 24 4
gpt4 key购买 nike

我正在对目前在 VS2017 中处于试验阶段的提议的 c++ 协同例程进行一些实验。我只是想有一个不返回任何东西但在某个协同例程对象上调用 co_await 的协同例程,比方说,在恢复之前在另一个线程上进行一些处理。但是,即使是最基本的返回void 的协程程序,VS 也不会编译。例如:

#include "stdafx.h"
#include <experimental\coroutine>

using namespace std::experimental;

void bob()
{
co_await suspend_always{};
}

int main()
{
bob();
}

导致错误:

1>c:\program files (x86)\microsoft visual studio\2017\professional\vc\tools\msvc\14.10.25017\include\experimental\resumable(46): error C2825: '_Ret': must be a class or namespace when followed by '::' 1>d:\dev\coroutinestest\main.cpp(10): note: see reference to class template instantiation 'std::experimental::coroutine_traits' being compiled 1>c:\program files (x86)\microsoft visual studio\2017\professional\vc\tools\msvc\14.10.25017\include\experimental\resumable(46): error C2510: '_Ret': left of '::' must be a class/struct/union 1>c:\program files (x86)\microsoft visual studio\2017\professional\vc\tools\msvc\14.10.25017\include\experimental\resumable(46): error C2061: syntax error: identifier 'promise_type' 1>c:\program files (x86)\microsoft visual studio\2017\professional\vc\tools\msvc\14.10.25017\include\experimental\resumable(46): error C2238: unexpected token(s) preceding ';'

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

谢谢

最佳答案

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

要使 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{}); 不会泄漏内存,它只是取消协程。

关于c++ - 为什么 VS2017 协程不能返回 void?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43245507/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com