This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 117a. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2025-04-13


3021. Subsumption rules for fold expanded constraints

Section: 13.5.5  [temp.constr.order]     Status: open     Submitter: Hubert Tong     Date: 2025-03-25

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.