如何检查有效的Boost.Asio CompletionToken?C++17优化方案问询
Boost.Asio CompletionToken 类型检查最优方案
Boost.Asio 并未直接提供is_completion_token这类类型特性,但可以利用其核心的async_result适配机制,实现通用且优雅的CompletionToken合法性检查,无需逐个枚举use_future_t、use_awaitable_t等特殊类型。
核心思路
所有合法的CompletionToken(包括函数、lambda、use_future、use_awaitable及自定义适配类型),都能被boost::asio::async_result针对特定操作签名完成实例化。我们可以基于这一点,通过SFINAE构建通用的类型检查 trait。
实现代码
#include <boost/asio/async_result.hpp> #include <boost/asio/use_future.hpp> #include <boost/asio/use_awaitable.hpp> #include <type_traits> #include <boost/system/error_code.hpp> // 通用CompletionToken检查 trait,依赖操作签名 template <typename CompletionToken, typename Signature, typename = void> struct is_completion_token : std::false_type {}; template <typename CompletionToken, typename Signature> struct is_completion_token<CompletionToken, Signature, std::void_t<typename boost::asio::async_result<std::decay_t<CompletionToken>, Signature>::type>> : std::true_type {}; // 辅助变量模板,简化使用 template <typename CompletionToken, typename Signature> constexpr bool is_completion_token_v = is_completion_token<CompletionToken, Signature>::value;
在异步函数中使用
假设你的异步操作完成时,会以(boost::system::error_code, int)的签名调用CompletionToken,那么可以这样限制模板参数:
template <typename CompletionToken, std::enable_if_t<is_completion_token_v<CompletionToken, void(boost::system::error_code, int)>, int> = 0> auto async_do_something(CompletionToken&& token) { // 利用async_result推导返回类型 using result_t = typename boost::asio::async_result<std::decay_t<CompletionToken>, void(boost::system::error_code, int)>::type; // 初始化异步完成逻辑 boost::asio::async_completion<CompletionToken, void(boost::system::error_code, int)> init(token); // ... 此处编写异步操作触发逻辑,完成后调用init.completion_handler传递结果 return init.result.get(); }
方案优势
- 通用性强:自动兼容所有符合Asio规则的CompletionToken,包括官方提供的特殊类型和自定义适配类型,无需手动添加类型枚举。
- 精准过滤:自动排除
int等完全不符合的类型,因为async_result无法对这类类型完成实例化。 - C++17兼容:基于
std::void_t实现,符合C++17标准要求。
注意事项
- 必须确保
trait中使用的Signature与异步操作最终调用CompletionToken的签名完全一致,比如无参场景下签名为void(),单参数场景为void(boost::system::error_code)等。 - 使用
std::decay_t处理CompletionToken的类型,避免引用、cv限定符对async_result实例化的影响。
内容的提问来源于stack exchange,提问作者Takatoshi Kondo
相关产品推荐
相关产品推荐

