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

将封装为shared_ptr的Socket传入方法时,Boost.Beast tcp_stream触发删除函数错误

问题分析与解决:Boost.Asio+Beast编译错误(use of deleted function)

问题场景

使用Boost.Asio开发网络程序时,编写了如下代码:

void connections::start_acceptor(){

    auto socket=std::make_shared<boost::asio::ip::tcp::socket>(ioc);

    con_acceptor.async_accept(*socket,[this,socket](const boost::system::error_code ec){

        if(!ec){

            this->status=true;

            if(socket->is_open()){

                cout<<"client connection Acknoledged with ip - "<<socket->remote_endpoint()<<endl;

                boost::asio::spawn(con_acceptor.get_executor(), [this,socket](boost::asio::yield_context yield) {

                    r_w_handler(socket, yield);

                });

            };

            this->start_acceptor();

        } else{

            cout<<"Error Accepting - "<<ec.message()<<endl;

            this->status=false;

            this->start_listener();

        }

    });
};


void connections::r_w_handler(std::shared_ptr<boost::asio::ip::tcp::socket> socket, boost::asio::yield_context yield) {

        boost::beast::tcp_stream stream_socket(*socket);

        try {

            char data[128];

            for (;;) {

                // std::size_t length = socket->async_read_some(boost::asio::buffer(data), yield);

                // boost::asio::async_write(*socket, boost::asio::buffer(data, length), yield);

            }

        } catch (const std::exception& e) {

            std::cerr <<" Error with session " << e.what() << std::endl;

        }

};

编译时触发错误:

error: use of deleted function

boost::asio::basic_stream_socket<Protocol, Executor>::basic_stream_socket(const boost::asio::basic_stream_socket<Protocol, Executor>&) [with Protocol = boost::asio::ip::tcp; Executor = boost::asio::any_io_executor]

原因分析

错误核心是**boost::asio::ip::tcp::socket是不可拷贝类型**,其拷贝构造函数被显式删除。

代码中boost::beast::tcp_stream stream_socket(*socket);这一行,试图通过拷贝*socket(原始socket对象)初始化tcp_stream,但tcp_stream的构造函数接收socket对象时会尝试拷贝,而socket不允许拷贝,因此触发编译错误。

解决方法

有两种可行的解决方式:

方式一:移交socket所有权给tcp_stream

用std::move转移socket的所有权,避免拷贝操作。修改r_w_handler中的初始化代码:

// 转移socket所有权给tcp_stream
boost::beast::tcp_stream stream_socket(std::move(*socket));

注意:所有权移交后,原shared_ptr<socket>指向的对象会失效,后续不能再通过该shared_ptr操作socket。

方式二:让tcp_stream共享底层套接字资源

若需保留原socket的使用,可通过socket的执行器和原生句柄构造tcp_stream:

boost::beast::tcp_stream stream_socket(socket->get_executor());
stream_socket.assign(socket->native_handle());

这种方式下,tcp_stream与原socket共享底层套接字,需注意避免双重关闭或操作冲突。

推荐优先使用方式一,契合Boost.Beast的设计理念:让tcp_stream接管套接字生命周期,更好地利用其资源管理机制。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 09:21:09