boost :: ref和boost :: asio完成处理程序,传递引用

时间:2011-09-02 11:40:55

标签: c++ functional-programming pass-by-reference boost-asio boost-ref

m_io_service.post(boost::ref(i));

我在一段代码中有这个调用,底层类型i绝对是可调用的(因为删除boost :: ref会导致传递值,这很好),但是clang告诉我:

/opt/dev_64_swat/proto-rpc2/dependencies/boost/include/boost/asio/handler_invoke_hook.hpp:64:3: error: type 'boost::reference_wrapper<rubble::rpc::TcpFrontEndConnectionInvoker>' does not provide a call operator

如何通过引用传递,我的对象比异步调用更长,并且如果我可以通过引用传递它们,它们会更优雅(减少boost :: shared_ptr&lt; ..&gt;作为成员)。< / p>

- 编辑 -

我已经浏览了asio的示例目录,并且没有为完成处理程序演示boost::ref。所以我想我在这里运气不好。有没有理由为什么处理程序没有版本接受ref?

- 编辑2:我的样子(除非你对实施有所怀疑,否则不要去看这个)。 -

namespace rubble { namespace rpc {
  struct InProcessInvoker : public InvokerBase
  {
    struct notification_object_
    {
      typedef notification_object_ * ptr;

      notification_object_()
      {
        reset();
      }
      void reset()
      {
        ready = false;
      }
      bool ready;
      boost::mutex mutex;
      boost::condition_variable cond;
    };

    InProcessInvoker(BackEnd & b_in)
      : b(b_in),
        notification_object(new notification_object_())
    {
      b.connect(m_client_data);
    }

    ~InProcessInvoker()
    {
      if( m_client_data.unique() )
      {
        b.disconect(m_client_data);
        delete notification_object;
      }
    }

    bool is_useable()
    {
      return b.is_useable();
    }

    void reset()
    {
      notification_object->reset();
      m_client_data->request().Clear();
      m_client_data->response().Clear();
      m_client_data->error_code().clear();
      BOOST_ASSERT_MSG( m_client_data->is_rpc_active() == false,
        "THE FLAG THAT REPRESENTS ACTIVE "
        "RPC SHOULD NOT BE SET WHEN RESETING AN OBJECT FOR RPC");
    }

    void invoke()
    {
      b.invoke(*this);
    }

    void operator() ()
    {
      service->dispatch(*client_cookie,*m_client_data);
      b.end_rpc(m_client_data.get());

      boost::lock_guard<boost::mutex> lock(notification_object->mutex);
      notification_object->ready=true;
      notification_object->cond.notify_one();
    }

    void after_post()
    {
      boost::unique_lock<boost::mutex> lock(notification_object->mutex);
      if(!notification_object->ready)
        notification_object->cond.wait(lock);
    }

    notification_object_::ptr notification_object;
    BackEnd & b;
  };

} }

2 个答案:

答案 0 :(得分:6)

boost::ref未提供operator()的重载。因此,返回不能直接用作回调。有两个选项:

  1. C ++ 03:使用boost::bind来包装ref,它会做你想做的事

    m_io_service.post(boost::bind<ReturnType>(boost::ref(i)))

    请注意,您必须指定返回类型,除非原始仿函数i具有result_type

  2. C ++ 11:改为使用std::ref,它提供了一个传递给包含引用的operator()

    m_io_service.post(std::ref(i))

答案 1 :(得分:2)

似乎boost::ref不适用于此类用途。 boost::ref提供了包装器,因此有问题的是,传递值或boost::ref会更有效,主要取决于您的可调用对象复制构造函数。作为解决方法,您可以使用boost::bind

m_io_service.post(boost::bind(&Callable::operator(), &i));