C++ Logo


Advanced search

Re: requires-clause, pack expansion and constraints-ordering

From: Lénárd Szolnoki <cpp_at_[hidden]>
Date: Mon, 29 Mar 2021 09:39:28 +0100
On Sun, 28 Mar 2021 13:44:00 +0100
Edward Catmur via Std-Discussion <std-discussion_at_[hidden]>

> You don’t need a(n explicit) pack expansion, or even for the pack to
> be non-empty. Simplifying your example to the point of absurdity:
> template<class> concept Any = true;
> template<class T> concept Sub = Any<T> && true;
> template<Any = void, Any...> int foo();
> template<Sub = void, Any...> int foo();
> int x = foo(); // rejects-valid, ambiguous call to overloaded function
> I’d class this as a bug in all compilers owing to incomplete coverage
> of the intersection between concepts and variadics. Yes it’s unusual
> for all compilers to have the same bug, but it isn’t unheard of.

Unfortunately this is not a bug in the compilers. A fold expression
over constraints counts as a single atomic constraint. Constraint
normalization only includes binary expressions involving && and || as
conjunction and disjunction.


The other abbreviated forms of applying constraints to type packs are
also subject to this, they are rewritten to `requires (Cpack && ...)`
with the fold expression, and not rewritten immediately to the unpacked
chain of binary && expressions.


I remember having this discussion before on the cpplang slack, but I
don't remember the motivation, I am also curious.


Received on 2021-03-29 03:39:38