c++ - 使用 boost:bind 绑定(bind)一个 std::function

标签 c++ function boost boost-bind

我在将 boost::bind 与存储在 std::function 中的函数一起使用时遇到问题。

这与 boost::asio 有关:我正在构建一个基本的 UDP 服务器。 所以,首先让我们看一些编译良好的代码没有 std::function(整个代码on Coliru here,取消注释定义以查看问题):

这里只有相关的部分:

class udp_server
{
        void start_receive()
        {
            _socket.async_receive_from(
                boost::asio::buffer( _buffer ),
                _remote_endpoint,
                boost::bind(
                    &udp_server::_rx_handler,
                    this,
                    boost::asio::placeholders::error,
                    boost::asio::placeholders::bytes_transferred,
                    42
                )
            );
        }

        void _rx_handler( const boost::system::error_code&, std::size_t bytes_rx, int );
};

如您所见,我将处理程序 _rx_handler(也称为“回调”)传递给 boost::asio 函数,以便在接收到某些内容时调用该函数。 因为我需要第三个参数并且“asio”函数需要特定的函数签名,所以我使用了 boost::bind。到目前为止一切顺利。

现在,我想将这个类继承到另一个类中,在那里我可以定义一些更具体的在接收数据时要做的事情。 所以我在基类中用具有相同签名的 std::function 替换了处理程序:

std::function< void( const boost::system::error_code&, std::size_t bytes_rx, int )> _rx_handler;

或者,更方便的是,使用 typedef;

typedef std::function< void( const boost::system::error_code&, std::size_t bytes_rx, int ) > CALLBACK_T;
...
CALLBACK_T _rx_handler;

这样(我想),我可以添加一个成员函数来分配来自继承类的任何成员函数:

void assignCallback( CALLBACK_T f )
{
    _rx_handler = f;
}

不幸的是,这不会编译。 GCC 5.4.1 说:

/usr/include/boost/bind/bind.hpp:69:37: error: ‘std::function udp_server::*’ is not a class, struct, or union type

但是当我检查 cppreference ,我读到它一个类模板...

看完这个页面后,我还尝试用target()访问函数指针:

boost::bind(
    &udp_server::_rx_handler.target(),
    this,
    boost::asio::placeholders::error,
    boost::asio::placeholders::bytes_transferred,
    42
)

但这也不编译:

error: no matching function for call to ‘std::function::target()’ udp_server::_rx_handler.target(),

问题:这里出了什么问题?我认为“真正的”函数和 std::function 可以互换吗? 我怎样才能使它工作?

附录:我觉得这可能与我对整个绑定(bind)的工作原理缺乏了解有关,所以感谢您的任何见解!

可能相关:std::function and std::bind: what are they & when they should be used?

最佳答案

您的绑定(bind)应修改如下:

void start_receive()
{
    _socket.async_receive_from(
        boost::asio::buffer( _buffer ),
        _remote_endpoint,
        boost::bind(
            udp_server::_rx_handler,
            boost::asio::placeholders::error,
            boost::asio::placeholders::bytes_transferred,
            42
        )
    );
}

你改变_rx_handler来自 void (udp_server::*)(const boost::system::error_code&, std::size_t bytes_rx, int);std::function<void(const boost::system::error_code&, std::size_t bytes_rx, int)>

因此您不再需要将实例绑定(bind)到 udp_server .

关于c++ - 使用 boost:bind 绑定(bind)一个 std::function,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48419946/

相关文章:

javascript - 如何在 JavaScript 中将前一个函数的结果绘制到新函数中

c++ - 图实现的邻接矩阵中的数组 vector 错误

c++ - 如何获取 ICU 中的所有时区名称

c++ - 使用 C++ 的 OpenCV 中的特征脸

c++ - 应用程序崩溃并显示 "symbol _ZdlPvm, version Qt_5 not defined in file libQt5Core.so.5 with link time reference"

javascript - 返回函数和使用 function.innerFunction 有什么区别?

c++ - 生成 url 的唯一哈希键

c++ - Boost 线程中断在跨越 DLL 边界时不起作用

c++ - 有没有办法在 Visual Studio 中右键单击某个项目并直接转到文档?

c++ - 带图形的 c/c++ 赛车游戏