You may want to check this code example taken from libstdc++ in Gcc 4.6.1 and which I slightly modified to work with MSVC 2010 :
/!\ : is_default_constructible returns true even if the default constructor is private or protected, i still can't find a way to solve this, any idea ?) :
namespace std {
namespace detail {
template<typename _B1, typename _B2>
struct __and_
: public conditional<_B1::value, _B2, _B1>::type
{ };
template<typename _Pp>
struct __not_
: public integral_constant<bool, !_Pp::value>
{ };
template<typename _Tp>
struct __is_array_known_bounds
: public integral_constant<bool, (extent<_Tp>::value > 0)>
{ };
template<typename _Tp>
struct __is_array_unknown_bounds
: public __and_<is_array<_Tp>, __not_<extent<_Tp>>>::type
{ };
struct __do_is_default_constructible_impl
{
template<typename _Tp>
static true_type __test(int,decltype(_Tp())* a = 0);
template<typename>
static false_type __test(...);
};
template<typename _Tp>
struct __is_default_constructible_impl
: public __do_is_default_constructible_impl
{
typedef decltype(__test<_Tp>(0)) type;
};
template<typename _Tp>
struct __is_default_constructible_atom
: public __and_<__not_<is_void<_Tp>>,
__is_default_constructible_impl<_Tp>>::type
{ };
template<typename _Tp, bool = is_array<_Tp>::value>
struct __is_default_constructible_safe;
// The following technique is a workaround for a current core language
// restriction, which does not allow for array types to occur in
// functional casts of the form T(). Complete arrays can be default-
// constructed, if the element type is default-constructible, but
// arrays with unknown bounds are not.
template<typename _Tp>
struct __is_default_constructible_safe<_Tp, true>
: public __and_<__is_array_known_bounds<_Tp>,
__is_default_constructible_atom<typename
remove_all_extents<_Tp>::type>>::type
{ };
template<typename _Tp>
struct __is_default_constructible_safe<_Tp, false>
: public __is_default_constructible_atom<_Tp>::type
{ };
} // namespace detail
/// is_default_constructible
template<typename _Tp>
struct is_default_constructible
: public integral_constant<bool, (detail::__is_default_constructible_safe<
_Tp>::value)>
{ };
}
use :
class DefaultConstructible
{
public:
DefaultConstructible() {}
};
class NotDefaultConstructible
{
public:
NotDefaultConstructible(int i) {}
};
std::is_default_constructible<DefaultConstructible>::value // -> true
std::is_default_constructible<NotDefaultConstructible>::value // -> false