本文接着探讨准备进入C++20的Coroutine。
根据之前的介绍,以及参考下面两篇文章,文本实操演示一个Coroutine。
- Beginning the coroutine with Visual Studio 2015 Update 3 Part 1
- Beginning the coroutine with Visual Studio 2015 Update 3 Part 2
将下面的代码保存为co.cpp。在Visual Studio 2019的命令行中,可以使用cl /await /std:c++latest /EHsc co.cpp
来编译这个源码文件。
#include <iostream>
#include <experimental/resumable>
using namespace std;
using namespace std::experimental;
struct resumable_thing
{
struct promise_type
{
resumable_thing get_return_object()
{
return resumable_thing(coroutine_handle<promise_type>::from_promise(*this));
}
auto initial_suspend() { return suspend_never{}; }
auto final_suspend() { return suspend_never{}; }
void return_void() {}
};
coroutine_handle<promise_type> _coroutine = nullptr;
resumable_thing() = default;
resumable_thing(resumable_thing const&) = delete;
resumable_thing& operator=(resumable_thing const&) = delete;
resumable_thing(resumable_thing&& other)
: _coroutine(other._coroutine) {
other._coroutine = nullptr;
}
resumable_thing& operator = (resumable_thing&& other) {
if (&other != this) {
_coroutine = other._coroutine;
other._coroutine = nullptr;
}
}
explicit resumable_thing(coroutine_handle<promise_type> coroutine) : _coroutine(coroutine)
{
}
~resumable_thing()
{
if (_coroutine) { _coroutine.destroy(); }
}
void resume() { _coroutine.resume(); }
};
resumable_thing counter() {
cout << "counter: called\n";
for (unsigned i = 1; ; i++)
{
co_await std::experimental::suspend_always{};
cout << "counter:: resumed (#" << i << ")\n";
}
}
int main()
{
cout << "main: calling counter\n";
resumable_thing the_counter = counter();
cout << "main: resuming counter\n";
the_counter.resume();
the_counter.resume();
the_counter.resume();
the_counter.resume();
the_counter.resume();
cout << "main: done\n";
return 0;
}
上面代码的输出:
main: calling counter
counter: called
main: resuming counter
counter:: resumed (#1)
counter:: resumed (#2)
counter:: resumed (#3)
counter:: resumed (#4)
counter:: resumed (#5)
main: done
参考
Vendors
- Coroutines in LLVM — LLVM 10 documentation
- Coroutine Archives | C++ Team Blog
- Resumable functions in C++
- More about resumable functions in C++
- Using C++ Resumable Functions with Libuv
- resumable functions - async and await
yield
keyword to becomeco_yield
in VS 2017- C++ - From Algorithms to Coroutines in C++
Compiler
(本篇完)