This is the mail archive of the mailing list for the GCC project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [c++-concepts] Constrained friends

On 09/13/2013 12:21 PM, Andrew Sutton wrote:
Previously, if constraints were not
satisfied, we would not record the template as a candidate. However,
this causes errors in class template instantiation if there are
constrained friend declarations whose constraints are not satisfied
("no matching template declaration").

Is that wrong? We normally give errors about friend declarations that don't match any template. Why don't we want this error when the friend declaration is looking for a constrained template?

+  if (is_non_template_member_fn (fn) || is_non_template_friend (fn))

Let's have one predicate instead of two; the condition here is a temploid that is not a specialization of a primary template.

+      if (!check_template_constraints (tmpl, args) && (complain & tf_error))
           reason = template_constraint_failure (tmpl, args);
           viable = false;

Why add the complain check? A constraint failure should make a candidate non-viable even in SFINAE context.

+  // If we're not instantiating a friend function, then we need to
+  // ensure the specialization of the best template satisfies its
+  // constraints.

Surely we need to check constraints in the earlier loop, so that we don't treat as a candidate a template that doesn't satisfy the constraints; otherwise if we have two templates

template <class T> T f(T) requires Thing;
template <class T> T* f(T*);

and our specialization requires Thing, we would select the second (because it is otherwise more specialized) and then give an error about constraint mismatch; I would think we want to select the first.

+        // If there is an overload with the same type and
+        // constraints, then this is a good declaration.
+        if (same_type_p (TREE_TYPE (fn), TREE_TYPE (f)))
+          if (equivalent_constraints (constr, get_constraints (f)))
+            return;

It seems that this will only allow friend declarations that match the template exactly, not friend declarations that are more specialized than the matching template. It looks like you're trying to implement a subset of determine_specialization here, which I think is a mistake.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]