Boost logo

Boost Users :

Subject: [Boost-users] strange nested bind behavior
From: Zachary Turner (divisortheory_at_[hidden])
Date: 2009-06-24 17:59:08


I have a couple of classes that all have a few functions with
identical names and signatures. Some of these common functions are
template functions where one of the arguments to the function is a
callback. For example.

class Foo
{
   template<typename Handler>
   void func(int x, Handler callback)
};

class Bar
{
   template<typename Handler>
   void func(int x, Handler callback)
};

Somewhere else, I have a class such as:

class Test
{
   variant<Foo&, Bar&> variant_obj;

   void callback(double d, float f, boost::system::error_code ec, size_t s);
   void test();
};

and i want to invoke func on the object represented by the variant,
with the callback going to this->callback, bind the values of d and f
from the place I invoke the visitor, and allowing the implementation
of func to specify the values of ec and s.

Hopefully this makes sense. I've done the following:

struct func_visitor : public boost::static_visitor<>
{
    template<typename T, typename Handler>
    void operator()(T& t, int x, Handler h) const
    {
        t.func(x, h);
    }
};

//...

void Test::test()
{
    boost::apply_visitor(
        boost::bind(
            func_visitor(),
            _1,
            7,
            boost::protect(boost::bind(
                &Test::callback,
                this,
                3.0, 5.0f,
                _1,
                _2))),
        variant_obj);
}

So now, func should expect that Handler has the signature void
(error_code, size_t)

I compiled it with empty definitions for both occurences of func()
just to make sure everything was ok, then I implement one copy of func
as follows:

template<typename Handler>
void func(int x, Handler callback)
{
    callback(make_error_code(success), (size_t)0);
}

and now I get compilation error pointing to the line above that
invokes callback, with the error along the lines of (it's on a
different machine with no network access so i can't paste it)

void boost::_bi::protected_bind_t<F>::operator()<boost::system::error_code,
size_t>(A1&,A2&) const' : cannot convert parameter 2 from 'size_t' to
'size_t &'

If I change the above function to the following:

template<typename Handler>
void func(int x, Handler callback)
{
    size_t temp = 0;
    callback(make_error_code(success), temp);
}

then everything works. Is this normal, or is this some kind of bug in
either the library or my compiler? All of my function signatures take
arguments by value, so I'm not sure why it would want to convert it to
a reference first.


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net