
On Thu, 2007-09-20 at 21:19 +0200, Peter Bindels wrote:
I was thinking of a way to make a generic binder for a given parameter in a functor implemented with variadic templates. The binder needs (I think) to recurse in the type list to find the given type (to be extracted out of the typelist) and the rest of the typelist to instantiate the return value interface type, at least.
Sure, you can do that. There's a full implementation of tr1::bind in the upcoming GCC 4.3 (available from GCC's Subversion repository)s, and this requires a subset of that functionality. So it's doable, but it might not necessarily be easy. The implementation of tr1::bind is "lightly described" in N2080, the variadic templates proposal.
template <typename... Before, typename Item, typename... After> Bind<3, Before..., Item, After...>(const Functor<Before..., Item, After...> &, const Item &value) : public Functor<Before..., After...> {...}
To evaluate this expression you need to rewrite it so you can match the first parameter pack up with a certain amount of parameters given as an int. AFAIK, the only way to do that is to take it as a whole list and to split it up by myself:
Right, the above matching doesn't work.
template <typename... Args> Bind<3, Args...>(const Functor<Args...> &, const typeFrom<3, Args...>::type &) : public Functor<typeWithout<3, Args...>::types...> {...}
I'm puzzled how I can write typeWithout::types... without a parameter pack typedef. You might be able to go from the first idea to one that checks is_equal<sizeof<Before...>, 3>::value but I'm not sure the compiler can trace that route or whether it'll be possible.
You can do it with a metafunction that returns the equivalent of Functor<typeWithout<3, Args...>::types...> It will be a recursive metafunction that pulls apart "Args", skipping the third argument, and puts all of the other arguments into the Functor. An example: template<typename F, int N, typename... Args> struct functor_without_Nth_arg; template<typename... FArgs, int N, typename Arg, typename... Args> struct functor_without_Nth_arg<Functor<FArgs...>, N, Arg, Args...> : functor_without_Nth_arg<Functor<FArgs..., Arg>, N-1, Args...> { }; template<typename... FArgs, typename Arg, typename... Args> struct functor_without_Nth_arg<Functor<FArgs...>, 0, Arg, Args...> { typedef Functor<FArgs..., Args...> type; }; Now, functor_without_Nth_arg<Functor<>, 3, Args...>::type is the type you wanted. - Doug