常量引用传递的回调函数调用错误

时间:2020-10-01 16:08:15

标签: c++ lambda callback boost-asio

我目前在我的代码中遇到无法解决的“错误的函数调用”错误。显然,当调用TcpConnection :: start()方法时,我通过const引用传递给TcpConnection的回调为null /不再有效。

为简单起见,我在下面发布了一个简化的最小示例,其中不包含完整代码。如果这还不足以找出问题,我可以编辑我的问题并张贴其余代码。

我到目前为止还不是C ++专家,所以请耐心等待我:)

typedef std::function<void()> TcpMessageCallback;

class TcpConnection : public std::enable_shared_from_this<TcpConnection> {
public:
    typedef std::shared_ptr<TcpConnection> pointer;

    static pointer create(boost::asio::io_context &io_context, const TcpMessageCallback &cb) {
        return pointer(new TcpConnection(io_context, cb));
    }

    tcp::socket &socket() {
        return socket_;
    }

    void start() {
        onDataCallback(); // <---- ***Error happens here***
    }

private:
    TcpConnection(boost::asio::io_context &io_context, const TcpMessageCallback &cb)
    : socket_(io_context), onDataCallback(cb){};

    tcp::socket socket_;
    const TcpMessageCallback &onDataCallback;
};

class TcpServer {
public:
    explicit TcpServer(boost::asio::io_context &context, const TcpMessageCallback &cb) :
            io_context(context),
            acceptor(context, tcp::endpoint(tcp::v4(), TCP_PORT_NUMBER)),
            onDataReceivedCb(cb) {
        start_accept();
    }

private:
    void start_accept() {
        tcpConnection = TcpConnection::create(io_context, onDataReceivedCb);

        auto onAcceptCb = [objPtr = this](auto error) {
                    objPtr->handle_accept(error);
                };
        acceptor.async_accept(tcpConnection->socket(), onAcceptCb);
    }

    void handle_accept(const boost::system::error_code &error) {
        if (!acceptor.is_open())
        {
            return;
        }

        if (!error) {
            tcpConnection->start();
        }
        start_accept();
    }

    boost::asio::io_context &io_context;
    tcp::acceptor acceptor;
    TcpConnection::pointer tcpConnection;
    const TcpMessageCallback &onDataReceivedCb;
};

然后我将通过我自己传递的lambda函数启动TcpServer来使用它。

//... define context
auto server = TcpServer(io_context, []{ /*...*/});
io_context.run()

但是,当新连接到达时,该错误发生在TcpConnection :: start()处,在该处onDataReceived回调不知何故没有(或已删除?)函数引用。当我按值传递回调时,它可以工作。

这可能是什么原因,我该如何解决?

0 个答案:

没有答案