On Fri, Jul 26, 2024 at 04:42:36PM -0400, Patrick Palka wrote:
> > // P2963R3 - Ordering of constraints involving fold expressions
> > // { dg-do compile { target c++20 } }
> > 
> > template <class ...T> concept C = (__is_same (T, int) && ...);
> > template <typename V>
> > struct S {
> >   template <class ...U> requires (C<U...>)
> >   static constexpr bool foo () { return true; }
> > };
> > 
> > static_assert (S<void>::foo <int, int, int, int> ());
> > 
> > somehow the template parameter mapping needs to be remembered even for the
> > fold expanded constraint, right now the patch will see the pack is T,
> > which is level 1 index 0, but args aren't arguments of the C concept,
> > but of the foo function template.
> > One can also use requires (C<int, int, int>) etc., no?
> 
> It seems the problem is FOLD_EXPR_PACKS is currently set to the
> parameter packs used inside the non-normalized constraints, but I think
> what we really need are the packs used in the normalized constraints,
> specifically the packs used in the target of each parameter mapping of
> each atomic constraint?

But in that case there might be no packs at all.

template <class T> C = true;
template <class ...U> requires (C<T> && ...)
constexpr bool foo () { return true; }

If normalized C<T> is just true, it doesn't use any packs.
But the [temp.constr.fold] wording assumes it is a pack expansion and that
there is at least one pack expansion parameter, otherwise N wouldn't be
defined.

        Jakub

Reply via email to