将 C++ lambda 函数转换为 boost 中的类方法函数

问题描述 投票:0回答:1

我是一名自学成才的 C++ 程序员,试图学习更多知识。

我正在尝试修改位于此处的 boost ssl 示例:

https://www.boost.org/doc/libs/1_82_0/doc/html/boost_asio/example/cpp11/ssl/server.cpp

我正在使用 g++ 编译器和 c++20

服务器类中的do_accept()方法中有一个lambda函数:

acceptor_.async_accept(
     [this](const boost::system::error_code& error, tcp::socket socket)
     {
       if (!error)
       {
         std::make_shared<session>(
             boost::asio::ssl::stream<tcp::socket>(
               std::move(socket), context_))->start();
       }

       do_accept();
     });

我想将 lambda 函数更改为类方法。

我的方法是:

void server::acceptHandler(const boost::system::error_code& error, tcp::socket socket) {
...
}

当我尝试替换为: Acceptor_.async_accept(boost::bind(&server::acceptHandler, this, boost::asio::placehoders::error, tcp::socket));

我在 tcp::socket 之后的 ')' 上收到“错误:')' 标记之前预期的主表达式”

我也尝试过: Acceptor_.async_accept(boost::bind(&server::acceptHandler, this, boost::asio::placehoders::error, boost::placeholders:_2))

我得到:“错误:使用已删除的函数 'boost::asio::basic_stream_socket::basic_stream_socket) [with Protocol = boost::asio::ip::tcp; Executor = boost::asio::any_io_executor'

将 lambda 函数更改为方法函数的正确方法是什么。

c++ lambda boost
1个回答
0
投票

我想象了一些周围的代码:

住在科里鲁

#include <boost/asio.hpp>
#include <boost/asio/ssl.hpp>
#include <iostream>
namespace asio = boost::asio;
namespace ssl  = asio::ssl;
using asio::ip::tcp;

struct session : std::enable_shared_from_this<session> {
    session(boost::asio::ssl::stream<tcp::socket> s) : stream_(std::move(s)) {}
    void start() {
        std::cout << "Accepted connection from " << stream_.lowest_layer().remote_endpoint() << "\n";
        stream_.async_handshake(ssl::stream_base::server,
                                [self = shared_from_this()](boost::system::error_code ec) {
                                    if (!ec) {
                                        self->do_read();
                                    } else {
                                        std::cerr << "Handshake failed: " << ec.message() << "\n";
                                    }
                                });
    }

  private:
    void do_read() {
        stream_.async_read_some(
            asio::buffer(data_),
            [self = shared_from_this()](boost::system::error_code ec, size_t bytes_transferred) {
                if (!ec) {
                    std::cout << "Received " << bytes_transferred << " bytes\n";
                    self->do_read();
                } else {
                    std::cerr << "Read failed: " << ec.message() << "\n";
                }
            });
    }
    ssl::stream<tcp::socket> stream_;
    std::array<char, 1024>   data_;
};

struct Server {
    Server(asio::any_io_executor ex, uint16_t port) : acc_(ex, {{}, port}) {
        // TODO load certificate and private key
        do_accept();
    }

  private:
    void do_accept() {
        acc_.async_accept([this](boost::system::error_code const& error, tcp::socket socket) {
            if (!error) {
                std::make_shared<session>(ssl::stream<tcp::socket>(std::move(socket), context_))->start();
            }

            do_accept();
        });
    }
    tcp::acceptor acc_;
    ssl::context  context_{ssl::context::tlsv12};
};

int main() {
    asio::thread_pool ctx;

    Server srv(ctx.get_executor(), 8989);

    ctx.join();
}

因为我将证书留给读者作为练习,所以这是关于它可以做什么:

enter image description here

更改 lambda

现在,我不知道你为什么想要它,但你可以:

void do_accept() {
    acc_.async_accept(std::bind( //
        &Server::on_accept, this, std::placeholders::_1, std::placeholders::_2));
}

void on_accept(boost::system::error_code const& error, tcp::socket socket) {
    if (!error) {
        std::make_shared<session>(ssl::stream<tcp::socket>(std::move(socket), context_))->start();
    }

    do_accept();
}

请注意,

tcp::socket
是一种类型,而不是占位符。

© www.soinside.com 2019 - 2024. All rights reserved.