boost::bind don't compile with member template function

c++

Solution

There's a (non-obvious) feature of `boost::bind` involved here. http://www.boost.org/libs/bind/#nested_binds

If you write:

void func1(int len) {return len+1;};
int func2(std::string str) {return str.length();};

assert(
    boost::bind(func1, boost::bind(func2, _1) )("Hello")
    == 6 );

`boost::bind` assumes that what you meant is "run `func2` on `"Hello"`, then run `func1` on the result". This allows more interesting partial function application.

In your program, you have an expression which amounts to:

boost::bind(&DerivedFinishAction::BindFunc<...>, 
            this, 
            boost::bind(&DerivedFinishAction::Inc, this))

So `boost::bind` tries to figure out how to run `DerivedFinishAction::Inc` on it arguments, so it can pass that result into `DerivedFinishAction::BindFunc<...>`. But `DerivedFinishAction::Inc` returns void, which cannot be passed into `DerivedFinishAction::BindFunc<...>`. Thus you get a compiler error:

/usr/include/boost/bind/bind.hpp:313:9: error: invalid use of void expression

Edit: Per the documentation, you can use `protect` to achieve your desired behavior:

#include <boost/bind/protect.hpp>
...
TmplFunc(boost::protect(boost::bind(&DerivedFinishedAction::Inc, this))); // no longer an error
...

Problem

I just write an simple example to test boost::bind. I use it to instantiate a template member function, but it won't compile with g++ 4.6.0. I don't know what's the problem. Here's the code: ``` #include <boost/bind.hpp> struct Functor { void operator()() { } }; struct DerivedFinishAction { DerivedFinishAction() {} void Inc() { } template <typename T> void TmplFunc(T t) { (boost::bind(&DerivedFinishAction::BindFunc<T>, this , t))(); } template <typename T> void BindFunc(T t) { t(); } void Func() { Functor f; TmplFunc(f); // this is OK TmplFunc(boost::bind(&DerivedFinishAction::Inc, this)); // compile error } }; int main(int argc, char *argv[]) { return 0; } ``` And g++ gives the following errors: ``` In file included from /usr/include/boost/bind.hpp:22:0, from testBind.cpp:1: /usr/include/boost/bind/bind.hpp: In member function ‘void boost::_bi::list2<A1, A2>::operator()(boost::_bi::type<void>, F&, A&, int) [with F = boost::_mfi::mf1<void, DerivedFinishAction, boost::_bi::bind_t<void, boost::_mfi::mf0<void, DerivedFinishAction>, boost::_bi::list1<boost::_bi::value<DerivedFinishAction*> > > >, A = boost::_bi::list0, A1 = boost::_bi::value<DerivedFinishAction*>, A2 = boost::_bi::bind_t<void, boost::_mfi::mf0<void, DerivedFinishAction>, boost::_bi::list1<boost::_bi::value<DerivedFinishAction*> > >]’: /usr/include/boost/bind/bind_template.hpp:20:59: instantiated from ‘boost::_bi::bind_t<R, F, L>::result_type boost::_bi::bind_t<R, F, L>::operator()() [with R = void, F = boost::_mfi::mf1<void, DerivedFinishAction, boost::_bi::bind_t<void, boost::_mfi::mf0<void, DerivedFinishAction>, boost::_bi::list1<boost::_bi::value<DerivedFinishAction*> > > >, L = boost::_bi::list2<boost::_bi::value<DerivedFinishAction*>, boost::_bi::bind_t<void, boost::_mfi::mf0<void, DerivedFinishAction>, boost::_bi::list1<boost::_bi::value<DerivedFinishAction*> > > >, boost::_bi::bind_t<R, F, L>::result_type = void]’ testBind.cpp:24:5: instantiated from ‘void DerivedFinishAction::TmplFunc(T) [with T = boost::_bi::bind_t<void, boost::_mfi::mf0<void, DerivedFinishAction>, boost::_bi::list1<boost::_bi::value<DerivedFinishAction*> > >]’ testBind.cpp:37:58: instantiated from here /usr/include/boost/bind/bind.hpp:313:9: error: invalid use of void expression ``` Can anybody help explain this? Why the first instantiation is OK while the second one causes compile error?

Original source