...目前世界上最受推崇、设计最精良的 C++ 库项目之一。
— Herb Sutter 和 Andrei Alexandrescu, C++ Coding Standards
提交一个完成令牌或函数对象以供执行。
template< typename Executor, typename NullaryToken = default_completion_token_t<Executor>> auto defer( const Executor & ex, NullaryToken && token = default_completion_token_t< Executor >(), constraint_t<(execution::is_executor< Executor >::value &&can_require< Executor, execution::blocking_t::never_t >::value)||is_executor< Executor >::value > = 0);
此函数使用指定的执行器提交一个对象以供执行。该函数对象将被排队等待执行,并且在从 defer()
返回之前,绝不会在当前线程中调用它。
与使用 post
相比,使用 defer()
表明调用者倾向于让执行器推迟函数对象的入队。这可能允许执行器针对函数对象代表当前调用上下文的延续的情况来优化入队。
目标执行器。
将用于生成完成处理程序的 完成令牌。完成处理程序的函数签名必须是
void handler();
此函数返回 async_initiate<NullaryToken, void()>(Init{ex}, token)
,其中 Init
是一个函数对象类型,定义如下:
class Init { public: using executor_type = Executor; explicit Init(const Executor& ex) : ex_(ex) {} executor_type get_executor() const noexcept { return ex_; } template <typename CompletionHandler> void operator()(CompletionHandler&& completion_handler) const; private: Executor ex_; // exposition only };
Init
的函数调用运算符:
通过执行以下操作获取处理程序的关联执行器对象 ex1
,类型为 Ex1
:
auto ex1 = get_associated_executor(handler, ex);
通过执行以下操作获取处理程序的关联分配器对象 alloc
:
auto alloc = get_associated_allocator(handler);
如果 execution::is_executor<Ex1>::value
为 true,则构造一个函数对象 f
,其中包含一个成员 executor_
,该成员初始化为 prefer(ex1, execution::outstanding_work.tracked)
,一个成员 handler_
,它是 completion_handler
的 decay-copy,以及一个执行以下操作的函数调用运算符:
auto a = get_associated_allocator(handler_); prefer(executor_, execution::allocator(a)).execute(std::move(handler_));
如果 execution::is_executor<Ex1>::value
为 false,则构造一个函数对象 f
,其中包含一个成员 work_
,该成员初始化为 make_work_guard(ex1)
,一个成员 handler_
,它是 completion_handler
的 decay-copy,以及一个执行以下操作的函数调用运算符:
auto a = get_associated_allocator(handler_); work_.get_executor().dispatch(std::move(handler_), a); work_.reset();
如果 execution::is_executor<Ex>::value
为 true,则执行:
prefer( require(ex, execution::blocking.never), execution::relationship.continuation, execution::allocator(alloc) ).execute(std::move(f));
如果 execution::is_executor<Ex>::value
为 false,则执行:
ex.defer(std::move(f), alloc);
void()