In short, why the code below behaves like described in the comments?
struct A
{
A() = delete;
//A(const A&) {} // uncommenting this...
};
int main()
{
A a{}; // ... breaks this
//A(); // this fails in either case because of `A() = delete;` only
}
What part of the standard (or at least a page on cppreference) should I look at to understand this?
However, writing A(const A&) = default; instead of //A(const A&) {} doesn't break A a{};. What about this? I think the underlying cause is the same, but a word from who really knows C++ is better than what I think.
Without the user-provided copy constructor,
Ais an aggregate. Yes, even though we deleted the default constructor. It's something that was addressed in C++20.So, prior to C++20,
A a{};is aggregate initialization, and so doesn't use the deleted constructor. When you uncomment the copy constructor,Astops being an aggregate, thus turning the aggregate initialization into value initialization. So the initialization ofawill attempt to call the deleted constructor.To divine the meaning of an initializer from the standard, one typically starts at [dcl.init]/16. Going through the bullets, one can find how the properties of the initializer (when matched with the properties of the types in question) will affect the way initialization occurs.