You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将类成员函数注册为boost::asio::tcp::acceptor::async_accept的回调?

问题描述

我可以成功将自由函数注册为async_accept()的回调:

void accept_cb(const boost::system::error_code& error, boost::asio::ip::tcp::socket socket)
{
    // 处理逻辑
}

[...]

_acceptor.async_accept(accept_cb); // 调用成功

但当我把accept_cb()改为类成员函数后,却无法成功注册到async_accept()中:

void tcp_server::accept_cb(const boost::system::error_code& error, boost::asio::ip::tcp::socket socket)

[...]

// 以下写法均编译失败
_acceptor.async_accept(boost::bind(&tcp_server::accept_cb, this, boost::asio::placeholders::error, boost::placeholders::_1));
_acceptor.async_accept(boost::bind(&tcp_server::accept_cb, this, boost::asio::placeholders::error, boost::placeholders::_2));
_acceptor.async_accept(boost::bind(&tcp_server::accept_cb, this, boost::placeholders::_1, boost::placeholders::_2));

正确的语法应该是什么?

注:我从Boost.Asio官方示例了解到boost::asio::placeholders::error,从Boost.Bind帮助文档了解到boost::placeholders::_1和::_2。

解决方案

正确的绑定写法需要统一使用Boost.Asio的专用占位符,并严格对应回调函数的参数顺序:

_acceptor.async_accept(
    boost::bind(&tcp_server::accept_cb, 
                this, 
                boost::asio::placeholders::error, 
                boost::asio::placeholders::socket)
);

关键说明

  1. 占位符需匹配异步操作的输出参数:async_accept的回调参数顺序固定为error_code在前、socket在后,Boost.Asio提供的boost::asio::placeholders::error和boost::asio::placeholders::socket会精准对应这两个位置,避免和Boost.Bind的通用占位符(_1/_2)混淆导致参数错位。
  2. 类成员函数必须绑定实例指针:绑定类成员函数时,必须将this作为boost::bind的第二个参数,让绑定器明确要调用哪个对象的成员函数。

如果使用C++11及以上标准,也可以用lambda表达式替代boost::bind,写法更直观:

_acceptor.async_accept(
    [this](const boost::system::error_code& error, boost::asio::ip::tcp::socket socket) {
        this->accept_cb(error, std::move(socket));
    }
);

内容的提问来源于stack exchange,提问作者Multisync

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 03:23:15