pass a boost::function as an argument to boost::bind

Discussion in 'C++' started by Christopher, Oct 2, 2011.

  1. Christopher

    Christopher Guest

    I want to make a callback that also calls back.
    I cannot get the code to compile.

    I read on the boost documentation about apply()., but the example is
    unclear and I am not sure if that is what I am looking for.

    /// Smart Pointer
    typedef boost::shared_ptr<TcpServerSideConnection> SmartPtr;

    /// Callback function pointer type for TcpListener notification that
    our execution of
    /// TcpServerSideConnection::OnConnectionAccepted has completed
    typedef boost::function<void(TcpServerSideConnection::SmartPtr
    newConnection,
    const boost::system::error_code &
    error)> ConnectionAcceptedListenerCallback;

    /// Callback function pointer type for TcpServerSideConnection
    notification of
    /// a TcpListener::Listen IO completion
    typedef boost::function<void(ConnectionAcceptedListenerCallback
    listenerCallback,
    const boost::system::error_code &
    error)> ConnectionAcceptedCallback;

    TcpListener::SmartPtr me = boost::dynamic_pointer_cast<TcpListener,
    TcpBaseSocket>(shared_from_this());

    TcpServerSideConnection::ConnectionAcceptedListenerCallback
    listenerCallback =
    boost::bind(&TcpListener::OnConnectionAccepted, me, _1, _2);

    TcpServerSideConnection::ConnectionAcceptedCallback
    acceptCompleteCallback =
    boost::bind(&TcpServerSideConnection::OnConnectionAccepted,
    newConnection, listenerCallback, boost::asio::placeholders::error);

    acceptor_.async_accept(newConnection->GetSocket(),
    acceptCompleteCallback);


    Gives me a compile error in bind.hpp with 100s of pages.

    What am I doing wrong here?
    Does anyone have an example of a callback that callsback using
    boost::bind?
    Christopher, Oct 2, 2011
    #1
    1. Advertising

  2. If I understand you correctly, 'accept' method should invoke
    callback, passing it a newly created connection and error code and
    this callback should invoke another one with the same parameters.

    Below is a short example for this, compiled with g++ 4.5.3 under
    cygwin
    I don't have boost, so I'm using tr1.

    #include <memory>
    #include <functional>
    #include <stdio.h>

    using std::placeholders::_1;
    using std::placeholders::_2;


    typedef int error_code_type;

    class TcpServerSideConnection;

    class TcpListener
    {
    public:
    typedef std::shared_ptr<TcpListener> SmartPtr;
    typedef std::function<void(std::shared_ptr<TcpServerSideConnection>
    newConnection, const error_code_type& error_code)>
    ConnectionAcceptedCallback;


    void accept(ConnectionAcceptedCallback cb);

    void
    OnServerConnectionAccepted(std::shared_ptr<TcpServerSideConnection>
    newConnection, const error_code_type& error_code)
    {
    printf("TcpListener::OnServerConnectionAccepted(%p)\n",
    newConnection.get());
    }
    };

    class TcpServerSideConnection
    {
    public:
    typedef std::shared_ptr<TcpServerSideConnection> SmartPtr;
    typedef std::function<void(SmartPtr newConnection, error_code_type &
    error_code)> ConnectionAcceptedCallback;

    TcpServerSideConnection()
    {
    printf("TcpServerSideConnection(%p)\n", this);
    }
    ~TcpServerSideConnection()
    {
    printf("~TcpServerSideConnection(%p)\n", this);
    }
    static void OnConnectionAccepted(SmartPtr newConnection, const
    error_code_type& error_code)
    {
    printf("TcpServerSideConnection::OnConnectionAccepted(%p)\n",
    newConnection.get());
    }

    static void OnConnectionAccepted2(SmartPtr newConnection,
    TcpListener::ConnectionAcceptedCallback accepted_cb, const
    error_code_type& error_code)
    {
    printf("TcpServerSideConnection::OnConnectionAccepted2(%p)\n",
    newConnection.get());
    accepted_cb(newConnection, error_code);
    }
    };

    void TcpListener::accept(ConnectionAcceptedCallback cb)
    {
    // make I/O here
    error_code_type err = 0;
    std::shared_ptr<TcpServerSideConnection> newConnection (new
    TcpServerSideConnection());
    printf("TcpListener::accept connection=%p\n", newConnection.get());
    cb(newConnection, err);
    }


    int main()
    {
    TcpListener::SmartPtr listener(new TcpListener());


    TcpListener::ConnectionAcceptedCallback listenerAcceptCompleted =
    &TcpServerSideConnection::OnConnectionAccepted;

    printf("[1] Call accept that callsback
    TcpServerSideConnection::OnConnectionAccepted\n");
    listener->accept( listenerAcceptCompleted );
    // or
    printf("[2] Call accept that callsback
    TcpServerSideConnection::OnConnectionAccepted\n");
    listener-
    >accept( std::bind(&TcpServerSideConnection::OnConnectionAccepted, _1,

    _2) );



    listenerAcceptCompleted =
    std::bind(&TcpListener::OnServerConnectionAccepted, listener, _1, _2);

    printf("[3] Call accept that callsback
    TcpServerSideConnection::OnConnectionAccepted2, which calls
    TcpListener::OnServerConnectionAccepted\n");
    listener-
    >accept( std::bind( &TcpServerSideConnection::OnConnectionAccepted2,

    _1, listenerAcceptCompleted, _2) );

    }
    Yakov Gerlovin, Oct 5, 2011
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Ben Kial
    Replies:
    1
    Views:
    616
    Eric Enright
    Nov 15, 2004
  2. Toby Bradshaw
    Replies:
    6
    Views:
    1,712
    Kai-Uwe Bux
    Jun 2, 2006
  3. Replies:
    0
    Views:
    573
  4. Reckoner
    Replies:
    11
    Views:
    674
    Steven D'Aprano
    Jan 19, 2009
  5. Mark
    Replies:
    1
    Views:
    415
    Jeff Flinn
    Nov 25, 2012
Loading...

Share This Page