Turns out that we have an issue report for this on WG21. It is public with github CWG issue 486.

I guess my question on the rationale is answered then. Seems to be non-intentional, as I hoped.

Johannes Schaub <schaub.johannes@googlemail.com> schrieb am Fr., 9. Feb. 2024, 15:08:


Lénárd Szolnoki via Std-Discussion <std-discussion@lists.isocpp.org> schrieb am Fr., 9. Feb. 2024, 14:41:
On Fri, 2024-02-09 at 14:01 +0100, Johannes Schaub via Std-Discussion
wrote:
> According to what I read on the Eelis draft, the following should
> resolve to the nonexplicit ctor (consistency gone, since it is
> different for non default ctors... what is the reason for this
> inconsistency?).
>
> But GCC and Clang raise an ambiguity. Why do they? This seems like a
> simple example.
>
> struct A { explicit A() { } A(int = 0) { } }; A a = {};

Overload resolution for copy-list-initialization is intentionally
different from overload resolution for copy-initialization.

https://eel.is/c++draft/dcl.init.list#3.5 applies. Value initialization
resolves to direct initialization from `()`, which is ambiguous.

It does not resolve to that. But it resolves to going to default initialization which enumerates candidate ctors by using over.match.ctor, which is sensitive to the context being copy initialization (which it is, here). The resulting candidates are then sent to overload resolution with the argument list resulting from an initializer "()". This algorithm is wholly different that your one-sentence summary.