[C++ PATCH] Fix unification of template template parameters (PRs 32565, 33943, 33965)

Doug Gregor doug.gregor@gmail.com
Mon Dec 17 20:43:00 GMT 2007


On Dec 17, 2007 1:36 PM, Jason Merrill <jason@redhat.com> wrote:
> Doug Gregor wrote:
> > +         /* The template parameter is something like TT<T> and the
> > +            template argument is something like X<A>.  Verify that
> > +            the template argument list of the template argument
> > +            (<T>) is compatible with the template argument list of
> > +            the template parameter (<A>).  This check is only an
> > +            initial check to determine feasibility of the
> > +            arguments; an exact check to determine whether it is
> > +            permitted to bind the template template parameter
> > +            (e.g., 'TT') to the template in the template argument
> > +            (e.g., 'X') will be handled by
> > +            template_template_parm_bindings_ok_p after all template
> > +            arguments have been deduced.  */
>
> In ttp25-27.C, TT<T> and X<A> are C<5> and X<5>, i.e. function
> parameter/argument, not template parameter/argument.

Yes, although the logic is the same here regardless of whether we're
checking function parameters/arguments or template
parameters/arguments.

> And you're
> checking to see if the template arguments <5> of X<5> are compatible
> with the template parameter list <T t> of C<t>.  Right?

Yes, although it's just a cursory check. It's not really a complete
check (hence the addition of template_template_parm_bindings_ok_p).

> It seems to me that it would be more appropriate to unify the template
> parameter lists for TT and X, rather than one parameter list and one
> argument list.  That way we when we compare C<5> to X<5> we would first
> compare C<T> to X<int> and deduce 'int' for T, so we shouldn't need
> template_template_parm_bindings_ok_p; deduction would then fail because
> we deduce 'int' from X<5> and 'long' from 5l, which don't match.

What happens if the type of a template non-type parameter is a
non-deduced context? Example:

  template<typename T> struct metafun { typedef T type; };

  template<typename T, template<typename metafun<T>::type> class C>
  void f(C<5>, T);

  template<int N> struct X {};
  void g() {
    f(X<5>(), 5);
  }

Now, we can't actually deduce the type 'T' from C's only template
parameter, so we're still stuck waiting until we've deduced 'T' before
we can check whether 'C' can be bound to 'X'. In this case it can (the
example is well-formed), but specialize metafun like so and the
example becomes ill-formed:

  template<> struct metafun<int> { typedef long type; };

So it seems like we still need template_template_parm_bindings_ok_p,
since we need to revisit the C --> X binding after we've deduced 'T'
from the second template type argument and substituted it into the
template parameter list of 'C'.  The code we have now to deal with
non-deduced types of template non-type parameters doesn't look into at
template parameter lists of template template parameters.

> This seems like a hole in the standard that ought to become a core
> issue: the standard doesn't say that you can deduce a type from a
> non-type template parameter of a template template argument, nor does it
> say that it is a nondeduced context.  I think this example is a strong
> argument for doing the deduction.

Well, [temp.deduct]p12 says that one cannot deduce template arguments
from any constructs not listed, so it's clear that it is not deduced.
I'm not particularly motivated by this example, but the extension
seems like a reasonable one. Actually, here's an interesting hack you
could do with this extension:

  template<typename> struct Weird;

  template<typename T, T Value, template<T> class C>
  struct Weird<C<Value> > {
    // I have a template template parameter C and I know it's argument
type... now what?
  };

So, I think this lets you do a better job at tearing part templates
that you don't know about, since it side-steps the prohibition on
deducing template type parameters from non-type template arguments
([temp.deduct.type]p13).

> Could you combine ttp25-27.C into one test?  I think that would be clearer.

Sure, I can do that. I'll also add in a few variants of the
non-deduced case above.

  - Doug



More information about the Gcc-patches mailing list