本文接着探讨准备进入C++20的Coroutine。

根据之前的介绍,以及参考下面两篇文章,文本实操演示一个Coroutine。

将下面的代码保存为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

Compiler

(本篇完)