Title
Subsumption rules for fold expanded constraints
Status
open
Section
13.5.5 [temp.constr.order]
Submitter
Hubert Tong

Created on 2025-03-25.00:00:00 last changed 1 month ago

Messages

Date: 2025-03-31.19:05:42

Consider:

  template <typename T>
  concept C = false;

  template <typename ...T>
  concept CC = (C<T> && ...);

  template <typename T> requires CC<T>
  struct A;

  template <typename T> requires CC<> && true
  struct A<T>; // okay, surprisingly

The subsumption rules for fold expanded constraints (13.5.5 [temp.constr.order] bullet 1.3 with the definition of "compatible for subsumption" in 13.5.2.5 [temp.constr.fold] paragraph 5) do not properly account for fold-expressions in concept definitions. For the example above, the partial specialization is considered to be more specialized (and its associated constraints can be satisfieid), even though the constraints of the primary template can never be satisifed.

Additionally, replacing fold expressions in a constraint expression with an analogous use of a defined concept breaks subsumption relationships:

  template <typename, unsigned = 0> constexpr bool Atomic = true;

  template <typename T> concept C = Atomic<T>;
  template <typename T> concept C2 = C<T> && Atomic<T, 1>;

  template <typename ...T> concept CC = (C<T> && ...);
  template <typename ...T> concept CC2 = (C2<T> && ...);

  template <typename ...T> requires (C<T> && ...)
  struct A;
  template <typename ...T> requires (C2<T> && ...)
  struct A<T ...>; // okay, compatible for subsumption

  template <typename ...T> requires CC<T ...>
  struct AA;
  template <typename ...T> requires CC2<T ...>
  struct AA<T ...>; // error

Introducing parameter mappings for such fold expanded constraints might be an approach to fixing the issue.

History
Date User Action Args
2025-03-25 00:00:00admincreate