4
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<..> がメンバーとして少ない)。

- 編集 -

asio の example ディレクトリを grep しましたが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;
  };

} }
4

2 に答える 2

6

boost::refのオーバーロードを提供しませんoperator()。したがって、リターンをコールバックとして直接使用することはできません。2つのオプションがあります:

  1. C ++ 03:boost::bindrefをラップするために使用すると、必要な処理が実行されます

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

    i元のファンクターに次のtypedefがない限り、リターンタイプを指定する必要があることに注意してください。result_type

  2. C ++ 11:std::ref代わりに使用します。これは含まれている参照にパススルーするoperator()を提供します

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

于 2011-09-02T12:00:30.713 に答える
2

boost::refそのような使用を意図していないようです。boost::refラッパーを提供するため、値渡しまたは値渡しのどちらがより効果的であるかは疑問ですがboost::ref、ほとんどの場合、呼び出し可能なオブジェクトコピーコンストラクターに依存します。回避策として、次を使用できますboost::bind

m_io_service.post(boost::bind(&Callable::operator(), &i));
于 2011-09-02T11:59:39.487 に答える