The compiler applies some fairly mechanical transformations to the code that you write to turn it into a state-machine that allows it to suspend execution at particular points within the function and then later resume execution.
The Promise object defines and controls the behaviour of the coroutine itself by implementing methods that are called at specific points during execution of the coroutine.
The facilities the C++ Coroutines TS provides in the language can be thought of as a low-level assembly-language for coroutines. These facilities can be difficult to use directly in a safe way and are mainly intended to be used by library-writers to build higher-level abstractions that application developers can work with safely.
C ++ Coroutines TS 提供的功能可以被认为是协程的一种低级汇编语言。这些功能可能很难以安全的方式直接使用,并且主要旨在供库编写人员用来构建更高级的抽象,以便应用程序开发人员可以安全地使用它们。
Compiler <-> Library interaction
Instead, it specifies a general mechanism for library code to customise the behaviour of the coroutine by implementing types that conform to a specific interface. The compiler then generates code that calls methods on instances of types provided by the library.
Coroutines generalise the operations of a function by separating out some of the steps performed in the Call and Return operations into three extra operations: Suspend, Resume and Destroy.
比其他文章多描述了一个 Destroy 步骤,更准确。
Note that, like the Return operation of a function, a coroutine can only be suspended from within the coroutine itself at well-defined suspend-points.
请注意,就像函数的 Return 操作一样,协程只能在定义好的暂停点处从协程自身内部暂停。
Coroutine activation frames
With coroutines there are some parts of the activation frame that need to be preserved across coroutine suspension and there are some parts that only need to be kept around while the coroutine is executing. For example, the lifetime of a variable with a scope that does not span any coroutine suspend-points can potentially be stored on the stack.
As I have mentioned in the previous posts, the suspend_always and suspend_never are types, that fulfill the Awaitable concept.
We can get the Awaitable object in two ways:
Direct creation of Awaitable,
Transformation of the object into Awaitable because of await_transform function.
co_await operator and Awaiter
The co_await operator is actually responsible for two things:
Forcing compiler to generate some coroutine boilerplate code
Creating the Awaiter object.
So first let’s have a look at how is the awaiter object is created. The co_await operator is responsible for the creation of the awaiter object. The co_await operator declaration is looked upon in the awaitable object and if it’s found this co_await operator is executed to obtain awaiter object. Otherwise, if the appropriate function is not found, then awaitable becomes the awaiter.
Main complaints were regarding the hardness to understand, lots of customisation points, and possibly not optimal performance due to possibly unoptimised dynamic memory allocations
主要的抱怨是关于理解起来很难,大量的定制点以及,未优化的动态内存分配可能造成性能的损失。
谷歌的提案存在一些问题,最终被接受的协程方案来自微软。
什么是协程
The coroutines already exist in many programming languages, may it be Python or C#. Coroutines provide one more way to create asynchronous code. How this way differs from threads and why do we need a dedicated language feature for coroutines and finally how we can benefit will be explained in this section.
std::function<> 模板到底是什么? 可以简单理解为对应 C 语言中的函数指针。入参或绑定的参数如果是原始指针或引用时,需要特别注意其生存周期。
关于函数类模板,学习《Effective.Modern.C++》P39
And maybe now you’re thinking “What’s a std::function object?” So let’s clear that up
boost::empty_value 的意义?
待补充
获得 std::function 对象
Lambda expressions
Constructs a closure: an unnamed function object capable of capturing variables in scope. 摘自 lambda
Function objects
A function object is any object for which the function call operator is defined. 摘自 functional
std::function,推荐查看其 Example
Class template std::function is a general-purpose polymorphic function wrapper. Instances of std::function can store, copy, and invoke any CopyConstructible Callable target – functions, lambda expressions, bind expressions, or other function objects, as well as pointers to member functions and pointers to data members. 摘自 function
需要强调的是 C++ 标准未对 std::bind 表达式的返回类型做出定义,其返回值并不对应我们熟悉的任何类型,但可以直接赋值给 std::function<>