title: boost::ref and boost::asio completion handlers, pass-by-reference
body: <pre><code>m_io_service.post(boost::ref(i));
  </code></pre>
  
  <p>I have this call in a section of code, the underlying type <code>i</code> is definetly a callable (because removing the boost::ref leads to pass by value, which works fine), however clang tells me that :</p>
  
  <pre><code>/opt/dev_64_swat/proto-rpc2/dependencies/boost/include/boost/asio/handler_invoke_hook.hpp:64:3: error: type 'boost::reference_wrapper&lt;rubble::rpc::TcpFrontEndConnectionInvoker&gt;' does not provide a call operator
  </code></pre>
  
  <p>How do I pass by reference, I have objects that outlive the asynchronous calls, and they would be more elegant (less boost::shared_ptr&lt;..> 's as members) if I could pass them by reference.</p>
  
  <p><strong>-- edit --</strong></p>
  
  <p>I have grepped through the example directory of asio, and <code>boost::ref</code> is not demonstrated for completion handlers. So I guess I am out of luck here. Is there a reason why the handlers don't have version accepting ref's ? </p>
  
  <p><strong>-- edit 2 : what I Looks like(don't bother looking at this unless you are suspicious of the implementation).  --</strong></p>
  
  <pre><code>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 &amp; 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-&gt;reset();
        m_client_data-&gt;request().Clear();
        m_client_data-&gt;response().Clear();
        m_client_data-&gt;error_code().clear();
        BOOST_ASSERT_MSG( m_client_data-&gt;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-&gt;dispatch(*client_cookie,*m_client_data);
        b.end_rpc(m_client_data.get());
  
        boost::lock_guard&lt;boost::mutex&gt; lock(notification_object-&gt;mutex);
        notification_object-&gt;ready=true;
        notification_object-&gt;cond.notify_one();
      }
  
      void after_post()
      {
        boost::unique_lock&lt;boost::mutex&gt; lock(notification_object-&gt;mutex);
        if(!notification_object-&gt;ready)
          notification_object-&gt;cond.wait(lock);
      }
  
      notification_object_::ptr notification_object;
      BackEnd &amp; b;
    };
  
  } }
  </code></pre>