On Tue, Jan 9, 2024 at 1:11 PM connor horman via Std-Proposals <std-proposals@lists.isocpp.org> wrote:
There's no copy-constructor call, though (not even an elided one, I believe copy-init from RHS of declarator never even tried to call a copy or move constructor).
copy-list-init doesn't call the copy constructor, it calls the list-init eligible converting constructor. It's converting from the empty initializer list, not a value constructed C.

Yes, and... (for Sean's further benefit)
In C++11-and-later, `{...}` denotes what I often call a "bag of arguments" — "given these arguments, implicitly convert them to the-thing-you-need on the LHS."
    std::pair<int, int> p1 = {1,2};  // "Given 1 and 2, make a pair"
    std::pair<int, int> p2 = {std::piecewise_construct, std::forward_as_tuple(1), std::forward_as_tuple() }; // "Given these three arguments, make a pair"
    std::pair<int, int> p3 = {};  // "Given nothing at all, make a pair"
The bag is allowed to be empty — as you see in `p3`'s initializer.

As a type author, if you have a class that's intended to be initialized from a sequence of zero or more elements, then you should give it a converting initializer-list constructor and also a converting default constructor, because (for historical reasons that might or might not make sense anymore) it's the default ctor that's going to be called in the zero-element scenario.
    std::vector<int> v1 = {};  // OK, converting default ctor
    std::vector<int> v2 = {1};  // OK, converting initializer-list ctor

If you have a class that's not intended to be initialized from an empty sequence (an empty bag of arguments), then you shouldn't give it a converting default constructor; you should make its default constructor `explicit` instead.
    Cat c1 = {};  // OK if the author wrote `Cat() = default`, but I hope they didn't
    Cat c2 = Cat();  // always OK, even if the author wrote `explicit Cat() = default` as I hope they did

The waters are quite muddied by the fact that the STL doesn't use this convention; the STL very consistently (but, from a green-field point of view, unwisely) makes all its constructors be converting constructors except for most single-argument constructors and in a very few ad-hoc other cases.

Related: https://quuxplusone.github.io/blog/2023/04/08/most-ctors-should-be-explicit/

Cheers,
Arthur