I think the standard just means "if T is a class type with deleted default constructor then goto default initialization". It would fail at last because the constructor selected for default initialization is deleted. It's used to distinguish with the 2nd case, i.e. "if T is a class type with a default constructor that is neither user-provided nor deleted", for that case zero-initialization is performed firstly, then default-initialization if T has a non-trivial default constructor.
A a{} is OK,but why?
Because when A is an aggregate type aggregate initialization is performed. Note that explicitly deleted constructors are allowed for aggregate type since C++11.
In all cases, if the empty pair of braces {} is used and T is an aggregate type, aggregate-initialization is performed instead of value-initialization.
And
An aggregate is one of the following types:
- ...
- class type (typically,
struct or union), that has - ...
- no user-provided, inherited, or explicit constructors (explicitly defaulted or deleted constructors are allowed) (since C++17) (until C++20)
- ...
EDIT
Since C++20 the behavior changed; A a{}; would fail.
An aggregate is one of the following types:
- ...
- class type (typically,
struct or union), that has - ...
- no user-declared or inherited constructors (since C++20)
- ...
A is not an aggregate again. A a{}; performs value-initialization (default-initialization), the deleted constructor is used and fails.
A a{}could work here.foo f{10};tofoo f{};.