Using bind with function objects

Hi, this test file doesn't compile, but why? $ LANG=en g++ bind.cpp -o bind && ./bind /usr/include/boost/bind.hpp: In member function 'R boost::_bi::list2<A1, A2>::operator()(boost::_bi::type<R>, F&, A&, long int) [with R = int, F = Foo, A = boost::_bi::list2<const char*&, const int&>, A1 = boost::arg<1> (*)(), A2 = boost::arg<2> (*)()]': /usr/include/boost/bind/bind_template.hpp:89: instantiated from 'typename boost::_bi::result_traits<R, F>::type boost::_bi::bind_t<R, F, L>::operator()(A1&, const A2&) [with A1 = const char*, A2 = int, R = int, F = Foo, L = boost::_bi::list2<boost::arg<1> (*)(), boost::arg<2> (*)()>]' bind.cpp:22: instantiated from here /usr/include/boost/bind.hpp:278: error: void value not ignored as it ought to be Thanks, Olaf

Behalf Of Olaf Peter wrote:
$ LANG=en g++ bind.cpp -o bind && ./bind /usr/include/boost/bind.hpp: In member function 'R boost::_bi::list2<A1, A2>::operator()(boost::_bi::type<R>, F&, A&, long int) [with R = int, F = Foo, A = boost::_bi::list2<const char*&, const int&>, A1 = boost::arg<1> (*)(), A2 = boost::arg<2> (*)()]': /usr/include/boost/bind/bind_template.hpp:89: instantiated from 'typename boost::_bi::result_traits<R, F>::type boost::_bi::bind_t<R, F, L>::operator()(A1&, const A2&) [with A1 = const char*, A2 = int, R = int, F = Foo, L = boost::_bi::list2<boost::arg<1> (*)(), boost::arg<2> (*)()>]' bind.cpp:22: instantiated from here /usr/include/boost/bind.hpp:278: error: void value not ignored as it ought to be
Foo::operator() is declared void and you are trying to bind it with bind<int>. If you change it to bind<void> that error will go away, but you will get another error about not being able to convert int into int&. I believe this because of the forwarding problem (see the boost bind documentation under "Limitations"). So, in order to make it work you need: struct Bar { Bar( Foo& foo_ ) : foo( foo_ ) { } void operator()( const char* s_ ) { bind<void>(foo, _1, 42)(s_); } Foo& foo; }; Hope this helps, -delfin

Delfin Rojas wrote:
Olaf Peter wrote:
$ LANG=en g++ bind.cpp -o bind && ./bind /usr/include/boost/bind.hpp: In member function 'R boost::_bi::list2<A1, A2>::operator()(boost::_bi::type<R>, F&, A&, long int) [with R = int, F = Foo, A = boost::_bi::list2<const char*&, const int&>, A1 = boost::arg<1> (*)(), A2 = boost::arg<2> (*)()]': /usr/include/boost/bind/bind_template.hpp:89: instantiated from 'typename boost::_bi::result_traits<R, F>::type boost::_bi::bind_t<R, F, L>::operator()(A1&, const A2&) [with A1 = const char*, A2 = int, R = int, F = Foo, L = boost::_bi::list2<boost::arg<1> (*)(), boost::arg<2> (*)()>]' bind.cpp:22: instantiated from here /usr/include/boost/bind.hpp:278: error: void value not ignored as it ought to be
Foo::operator() is declared void and you are trying to bind it with bind<int>. If you change it to bind<void> that error will go away, but you will get another error about not being able to convert int into int&. I believe this because of the forwarding problem (see the boost bind documentation under "Limitations"). So, in order to make it work you need:
struct Bar {
Bar( Foo& foo_ ) : foo( foo_ ) { }
void operator()( const char* s_ ) { bind<void>(foo, _1, 42)(s_); }
Foo& foo; };
Hope this helps,
Sorry, I meant: struct Bar { Bar( Foo& foo_ ) : foo( foo_ ) { } void operator()( const char* s_ ) { bind<void>(foo, _1, 42)(s_); } Foo& foo; }; That compiles for me in VC++ 8 -delfin

Thanks a lot, the wrong return type was stupid ...
struct Bar {
Bar( Foo& foo_ ) : foo( foo_ ) { }
void operator()( const char* s_ ) { bind<void>(foo, _1, 42)(s_); }
Foo& foo; };
That compiles for me in VC++ 8
yes, but I do not get the expected output, I was not carefully enough? $ ./bind X, 11

Hi, bind makes copies of the given parameters and operates on them. If you want bind to operate on a reference of the given object, you should use boost::ref. struct Bar { Bar( Foo& foo_ ) : foo( foo_ ) { } void operator()( const char* s_ ) { bind<void>(boost::ref(foo), _1, 42)(s_); } Foo& foo; }; This results in: $ ./a.out Hallo, 42 Greetings, Stefan On Do, 2008-02-28 at 21:04 +0100, Olaf Peter wrote:
Thanks a lot, the wrong return type was stupid ...
struct Bar {
Bar( Foo& foo_ ) : foo( foo_ ) { }
void operator()( const char* s_ ) { bind<void>(foo, _1, 42)(s_); }
Foo& foo; };
That compiles for me in VC++ 8
yes, but I do not get the expected output, I was not carefully enough?
$ ./bind X, 11

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Thursday 28 February 2008 15:04 pm, Olaf Peter wrote:
yes, but I do not get the expected output, I was not carefully enough?
$ ./bind X, 11
bind takes its arguments by value. You need to wrap the foo object in a boost::ref() call if you want to bind it as a reference. - -- Frank -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) iD8DBQFHyB465vihyNWuA4URAtkxAJ9yl/FgWOsT3zlDoXC2Q9UBTSs7nACePmT+ LnVEHdHuh0J/dzKrzl+BTCA= =AJE7 -----END PGP SIGNATURE-----
participants (4)
-
Delfin Rojas
-
Frank Mori Hess
-
Olaf Peter
-
Stefan Demharter