Boost logo

Boost :

From: Douglas Gregor (doug.gregor_at_[hidden])
Date: 2007-09-20 15:40:49


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


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk