Favicon

[Boost.Bind] Adding a single argument to an existing function, breaks the code.

Hi.

 	I am experiencing some issues with boost::bind and I was hoping if
anybody is willing to help me. The example is really simple:

First I have a function:

void com_client::handle_init(
         const std::string& host,
         const command_t command) {

     boost::asio::ip::tcp::resolver resolver(connection_.socket().io_service());
     boost::asio::ip::tcp::resolver::query query(host, service_);
     boost::asio::ip::tcp::resolver::iterator endpoint_iterator;
     endpoint_iterator = resolver.resolve(query);
     boost::asio::ip::tcp::endpoint endpoint = *endpoint_iterator;

     connection_.socket().async_connect(endpoint,
             boost::bind(
                     &com_client::handle_connect,
                     this,
                     2,
                     boost::asio::placeholders::error,
                     ++endpoint_iterator)
     );

}

After successful handshake, this function is called:

(Continue reading)

Steven Watanabe | 3 Jul 22:50

Re: [Boost.Bind] Adding a single argument to an existing function, breaks the code.

AMDG

Vjekoslav Brajkovic wrote:
> This issue is when I modify the code such that
>
>     connection_.socket().async_connect(endpoint,
>             boost::bind(
>                     &com_client::handle_connect,
>                     this,
>                     //2,
>                     boost::asio::placeholders::error,
>                     ++endpoint_iterator)
>     );
> <snip>
>
> enum command_t {
>     DEPOSIT_CHUNK = 2,
>     DETRIEVE_CHUNK = 4,
>     HEARTBEAT = 16
> };
>
> I was hoping if somebody could explain this. I've attached g++ output.

You can't convert from int to command_t implicitly.
Does it work if you pass DEPOSIT_CHUNK instead
of 2?

In Christ,
Steven Watanabe
(Continue reading)

Favicon

Re: [Boost.Bind] Adding a single argument to an existing function, breaks the code.

On Thu, 3 Jul 2008, Steven Watanabe wrote:
> You can't convert from int to command_t implicitly.
> Does it work if you pass DEPOSIT_CHUNK instead
> of 2?

Unfortunately not. Initially I was passing <command_t command> from
handle_init(), but then I decided to put value 2, so that I can isolate
the issue.

-V
Steven Watanabe | 4 Jul 00:08

Re: [Boost.Bind] Adding a single argument to an existing function, breaks the code.

AMDG

Vjekoslav Brajkovic wrote:
> On Thu, 3 Jul 2008, Steven Watanabe wrote:
>> You can't convert from int to command_t implicitly.
>> Does it work if you pass DEPOSIT_CHUNK instead
>> of 2?
>
> Unfortunately not. Initially I was passing <command_t command> from
> handle_init(), but then I decided to put value 2, so that I can isolate
> the issue.

Does it work if you use mem_fn?

            boost::bind(
                    boost::mem_fn(&com_client::handle_connect),
                    this,
                    2,
                    boost::asio::placeholders::error,
                    ++endpoint_iterator)

How about an explicit return type?

            boost::bind<void>(
                    &com_client::handle_connect,
                    this,
                    2,
                    boost::asio::placeholders::error,
                    ++endpoint_iterator)

(Continue reading)

Favicon

Re: [Boost.Bind] Adding a single argument to an existing function, breaks the code.

On Thu, 3 Jul 2008, Steven Watanabe wrote:

> Does it work if you use mem_fn?
>
>           boost::bind(
>                    boost::mem_fn(&com_client::handle_connect),
>                    this,
>                    2,
>                    boost::asio::placeholders::error,
>                    ++endpoint_iterator)
>
> How about an explicit return type?
>
>           boost::bind<void>(
>                    &com_client::handle_connect,
>                    this,
>                    2,
>                    boost::asio::placeholders::error,
>                    ++endpoint_iterator)
>
>

Nope. Same errors. I've tried both suggestions and their combinations
with no success.

V
Steven Watanabe | 4 Jul 01:57

Re: [Boost.Bind] Adding a single argument to an existing function, breaks the code.

AMDG

Vjekoslav Brajkovic wrote:
> On Thu, 3 Jul 2008, Steven Watanabe wrote:
>
>> Does it work if you use mem_fn?
>>
>> boost::bind(
>> boost::mem_fn(&com_client::handle_connect),
>> this,
>> 2,
>> boost::asio::placeholders::error,
>> ++endpoint_iterator)
>>
>> How about an explicit return type?
>>
>> boost::bind<void>(
>> &com_client::handle_connect,
>> this,
>> 2,
>> boost::asio::placeholders::error,
>> ++endpoint_iterator)
>>
>>
>
> Nope. Same errors. I've tried both suggestions and their combinations
> with no success.

Exactly the same errors? Including the third line of the error message?
I've marked that parts I would expect to be different.
(Continue reading)

Favicon

Re: [Boost.Bind] Adding a single argument to an existing function, breaks the code.

On Thu, 3 Jul 2008, Steven Watanabe wrote:
> Exactly the same errors? Including the third line of the error message?
> I've marked that parts I would expect to be different.
>
> /usr/local/include/boost-1_35/boost/bind/bind_template.hpp:15: instantiated 
> from ?boost::_bi::bind_t<
> **boost::_bi::unspecified** // void??
> , void (com_client::*)(command_t, const boost::system::error_code&, 
> boost::asio::ip::basic_resolver_iterator<boost::asio::ip::tcp>),
> //Something involving _mfi::?? ^^^^^^^^^^^
> boost::_bi:: list3<boost::_bi::value<com_client*>, boost::arg<1> (*)(),
> boost::_bi:: value<boost::asio::ip::basic_resolver_iterator<boost::asio::ip::tcp> 
>> > >?

Thank you for taking your time to solve my problem.

I've reproduced the output. Apparently, all of the outputs are the same.

-------------------------------------------------------
core dev/uleDFS/uleDFS% diff original.txt explicit.txt 
core dev/uleDFS/uleDFS% diff original.txt mem_fn.txt 
-------------------------------------------------------

>
> What is the type of boost::mem_fn(&com_client::handle_connect)?
> I usually get this information using
>
> # include <boost/mpl/assert.hpp>
> # include <boost/type_traits/is_same.hpp>
>
(Continue reading)

Steven Watanabe | 4 Jul 03:13

Re: [Boost.Bind] Adding a single argument to an existing function, breaks the code.

AMDG

Vjekoslav Brajkovic wrote:
> I've reproduced the output. Apparently, all of the outputs are the same.

Hmm. Interesting.

> I've added the code with the following results:
>
> ----------------------------------------------------------------------
> ../intercom/com_client.cpp:40: error: no matching function for call to
> ‘assertion_failed(mpl_::failed************
> boost::is_same<boost::_mfi::mf3<void, com_client, command_t,
> const boost::system::error_code&,
> boost::asio::ip::basic_resolver_iterator<boost::asio::ip::tcp>
> >, void>::************)’
> ----------------------------------------------------------------------
>
> Since I am not familiar with static assertion macros, I have no clue why
> it is complaining about 'no matching function for call'.

The point was to produce an error message that contains the type:

boost::_mfi::mf3<void, com_client, command_t,
const boost::system::error_code&,
boost::asio::ip::basic_resolver_iterator<boost::asio::ip::tcp>
 >

This is the correct type, so I have no idea what's going on.
Do you have a complete program that you can post which
(Continue reading)

Steven Watanabe | 4 Jul 03:19

Re: [Boost.Bind] Adding a single argument to an existing function, breaks the code.

AMDG

Vjekoslav Brajkovic wrote:
> Thank you for taking your time to solve my problem.

I just realized what's going on.

Take a look in the handle_client function, there's a second
call to bind with handle_client.  That's where the problem is.  You should
pass a command_t in both places.

        connection_.socket().async_connect(endpoint, boost::bind(
                &com_client::handle_connect, this,
                boost::asio::placeholders::error, ++endpoint_iterator));

In Christ,
Steven Watanabe
Favicon

Re: [Boost.Bind] Adding a single argument to an existing function, breaks the code.

On Thu, 3 Jul 2008, Steven Watanabe wrote:
>
> I just realized what's going on.
>
> Take a look in the handle_client function, there's a second
> call to bind with handle_client.  That's where the problem is.  You should
> pass a command_t in both places.
>
>       connection_.socket().async_connect(endpoint, boost::bind(
>                &com_client::handle_connect, this,
>                boost::asio::placeholders::error, ++endpoint_iterator));
>

Wow. I cannot believe it. I am sorry if I have wasted your time. Once
again, I really appreciate your help.

Best,
-V

Gmane