
Steve Lorimer wrote:
Hi
Is it possible to pass variadic template arguments to bind, such that bind uses them as the placeholder arguments (_1, _2, _3 etc)
I show my use case below. ... template<class T, typename... Args> struct cb { typedef void (T::*type)(Args...); }; ... job_t(typename cb<T, Args...>::type cb, boost::shared_ptr<T> that, boost::shared_ptr<job_queue> q) : arg_func(boost::bind(cb, that, Args...)), queue(q) {} // normally would be _1, _2, _3, etc
An interesting puzzle. I tried to apply the 'Indexes' technique shown in the bind implementation section of http://osl.iu.edu/~dgregor/cpp/variadic-templates.pdf and ended up with the following: #include <boost/bind.hpp> #include <boost/function.hpp> template<int...> struct int_tuple {}; // make indexes impl is a helper for make indexes template<int I, typename IntTuple, typename... Types> struct make_indexes_impl; template<int I, int... Indexes, typename T, typename... Types> struct make_indexes_impl<I, int_tuple<Indexes...>, T, Types...> { typedef typename make_indexes_impl<I+1, int_tuple<Indexes..., I>, Types...>::type type; }; template<int I, int... Indexes> struct make_indexes_impl<I, int_tuple<Indexes...> > { typedef int_tuple<Indexes...> type; }; template<typename... Types> struct make_indexes: make_indexes_impl<0, int_tuple<>, Types...> { }; template< class T, class... Args, int... Indexes > boost::function< void(Args...) > make_func_helper( void (T::* pm) (Args...), T * that, int_tuple< Indexes... > ) { return boost::bind( pm, that, boost::arg<Indexes+1>()... ); } template< class T, class... Args > boost::function< void(Args...) > make_func( void (T::* pm) (Args...), T * that ) { return make_func_helper( pm, that, typename make_indexes<Args...>::type() ); } struct X { void f( int, int ) { } }; int main() { X x; boost::function<void(int, int)> f = make_func( &X::f, &x ); f( 1, 2 ); } Hope this helps.