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]>
wrote:
> 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.
http://eel.is/c++draft/temp.constr#normal-1
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.
http://eel.is/c++draft/temp.param#4.sentence-4
I remember having this discussion before on the cpplang slack, but I
don't remember the motivation, I am also curious.
Cheers,
Lénárd
Edward Catmur via Std-Discussion <std-discussion_at_[hidden]>
wrote:
> 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.
http://eel.is/c++draft/temp.constr#normal-1
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.
http://eel.is/c++draft/temp.param#4.sentence-4
I remember having this discussion before on the cpplang slack, but I
don't remember the motivation, I am also curious.
Cheers,
Lénárd
Received on 2021-03-29 03:39:38