> but there's std::is_default_constructible also available of course:
There may be a cogent reason for rolling out a homegrown is_default_constructible
The problem with the mainstream implementations of std::is_default_constructible is that it ignores const qualifiers; for instance they would report that the type const int is default constructible.
Though, the standard does state these:
22.214.171.124 / Table 42
For template <class T> struct is_default_constructible; the condition is is_constructible_v<T> is true.
The predicate condition for a template specialization is_constructible<T, Args...> shall be satisfied if and only if the following variable definition would be well-formed for some invented variable t: T t(declval<Args>()...); http://eel.is/c++draft/meta.unary.prop
Checked this out with Cubbi; this was his response:
There are quite a few discrepancies between what the type traits check and what the similarly-named core language type requirements are. As far as I understand, the traits are what the library implementors find useful for the purposes of building generic libraries.
In the core language, default constructible means: can be constructed without an initialiser.
In the library, the concept DefaultConstructible means: can be constructed with an empty initialiser.
Cubbi has added this note to the cppreference page:
std::is_default_constructible<T> does not test that T x; would compile; it attempts direct-initialization with an empty argument list (see std::is_constructible). Thus, std::is_default_constructible_v<const int> and std::is_default_constructible_v<const int> are true. http://en.cppreference.com/w/cpp/types/is_default_constructible
Wow! Our little tete-a-tete reaches the hallowed portals of cppreference.com! Thank you JLBorges, Cubbi
As an aside, was aware any given compiler may not cover everything in the standard library and now learn that even the standard library may differ in subtle ways from the core language!
might these, in turn, be in line with what Cubbi's saying?:
If you look at the boost implementation linked earlier, is_default_constructible<T> tests whether "T()" compiles, except for when T is an array (in which case it tests the array element type) and when T is a reference type or a cv-void (in which case it hardcodes false)
So you can just compare your examples with T()'s behavior: