This is the mail archive of the
mailing list for the GCC project.
Re: [c++-concepts] Class template constraints
- From: Andrew Sutton <andrew dot n dot sutton at gmail dot com>
- To: Jason Merrill <jason at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org, Gabriel Dos Reis <gdr at cs dot tamu dot edu>
- Date: Wed, 4 Sep 2013 11:59:19 -0400
- Subject: Re: [c++-concepts] Class template constraints
- Authentication-results: sourceware.org; auth=none
- References: <CANq5SysAD-Dqupb5UVYJWx1c2_Bh2YbHMA86hdvk0J_dvPnPSA at mail dot gmail dot com> <52274F43 dot 5020002 at redhat dot com>
>> 1. Type constraints are checked on lookup rather than instantiation.
> How is this different from function template constraints? Is this just a
> difference in internal function name (instantiate_template vs
It's not supposed to be different. Checking constraints in
instantiate_template is actually too late. We want to check before
instantiation, at the point of use. This also means we don't need
complete types to check constraints. So this:
Should fail and does. This change also makes it impossible to have
partial specializations that are more general than the primary
template. Checking in lookup_class_template does not consult the
Constraints on partial specializations are checked in
most_specialized_class (or one of its subroutines).
>> +// Returns the type of a template specialization only if that
>> +// specializaiton needs to defined. Otherwise (e.g., if the type has
>> + // Do the constraints match the most general template? Note that
>> + // the absence of constraints will also match.
>> + if (equivalent_constraints (cur_constr, DECL_CONSTRAINTS (tmpl)))
> If absence matches, I think the name "equivalent" is misleading. But the
> implementation seems to require subsumes in both directions. What's up
Subsumption is essentially computing an implication between
constraints, so that if P subsumes Q, you could also say that P => Q.
Checking in both directions gives P => Q and Q => P, or P <=> Q, which
is logical equivalence.
I think that the absence of constraints fits into those definition
nicely, since it represents the empty set of propositions.
>> + // Find the template parameter list at the a depth appropriate to
>> + // the scope we're trying to enter.
>> + tree parms = current_template_parms;
>> + int depth = template_class_depth (type);
>> + for (int n = processing_template_decl; n > depth && parms; --n)
>> + parms = TREE_CHAIN (parms);
> If you're going to use this function from lookup_template_class_1, it can't
> use current_template_*, since those are parser state which might be
> something completely unrelated when we get here during instantiation.
I was worried about that. I'm not sure how this gets invoked during
instantiation. I'll look at it.