It uses the default constructor because list initialization with {} is meant to be a short form of value initialization always, disregarding of other constructors, even if they are initializer list constructors.
Is there anyway to differentiate the following two constructions: ...
The X() is always value initialization, while X{} is only value initialization if X has a default constructor. If it is an aggregate, then X{} is aggregate initialization (initializing the members of X by a {} recursively). If it only has initializer list constructors and no default constructors, then X() is invalid and X{} could be valid
struct A { A(initializer_list<int>); };
A a = A{}; // valid
A b = A(); // invalid
Essentially, what X{} does depends on what X is. But X() always value initializes.
... or return X(); vs return {};
Something subtle to mention... In return {} the target is copy-list-initialized, while in return X(); first direct-initializes an X. But even though it is copy-list-initialized, it can use an explicit default constructor, because value initialization doesn't care about explicit. However when you do return {} and you try to use an explicit non-default constructor you will error out
struct A {
explicit A(initializer_list<int>);
};
A f() { return {}; } // error!
struct B {
explicit B();
};
B g() { return {}; } // OK