strange nested bind behavior

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.

AMDG Zachary Turner wrote:
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 &
protect apparently doesn't even attempt perfect forwarding. I think that it should behave the same way as plain bind. Peter? In Christ, Steven Watanabe

Steven Watanabe:
AMDG
Zachary Turner wrote:
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 &
protect apparently doesn't even attempt perfect forwarding. I think that it should behave the same way as plain bind. Peter?
Yes, you are right. Feel free to fix it if you have the time. :-) If not, assign me a ticket.
participants (3)
-
Peter Dimov
-
Steven Watanabe
-
Zachary Turner