Boost logo

Boost :

From: Peter Bindels (dascandy_at_[hidden])
Date: 2007-09-20 15:19:45


On 20/09/2007, Doug Gregor <dgregor_at_[hidden]> wrote:
> It has not and will not be changed.
>
> It doesn't work because one would not be able to know when a
> dependent name is actually a parameter pack. Here's a short example:
>
> What is typename T::types, a type or a parameter pack of types? We
> absolutely have to know when the process the template whether this
> construct is a parameter pack or not, because it affects how pack
> expansions are processed. However, instantiating Storage with
> Foo<int, float> makes T::types a parameter pack, while instantiating
> Storage with Bar makes T::types a single type.

Ok, I understand.

> The "fix" for this is to do the same thing that "typename" does for
> "typename T::foo"... "typename" was added because the compiler can't
> tell whether T::foo is a a value or a type. We would need something
> like:
>
> typename... T::types
>
> to that say T::types is a type parameter pack. We'd need the same
> thing for value parameters packs and anything else that could be a
> parameter pack. It's not impossible to introduce such an extension,
> but doing so drastically increases the syntactic cost of variadic
> templates, and the addition of yet new things to worry about with
> dependent names makes variadic templates harder to use. For all
> these additions, you don't actually gain any expressive power:
>
> tuple<Types...> values;
>
> does basically the same thing as the requested functionality.

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.

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:

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.

Thanks for your time and patience,
Peter Bindels


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