Is there a way to test whether a C++ class has a default constructor (other than compiler-provided type traits)?

后端 未结 7 2133
花落未央
花落未央 2020-11-28 13:00

Traits classes can be defined to check if a C++ class has a member variable, function or a type (see here).

Curiously, the ConceptTraits do not include traits to che

7条回答
  •  时光取名叫无心
    2020-11-28 13:08

    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
    struct __and_
      : public conditional<_B1::value, _B2, _B1>::type
    { };
    
    template
    struct __not_
      : public integral_constant
    { };
    
    
    template
    struct __is_array_known_bounds
      : public integral_constant::value > 0)>
    { };
    
    template
    struct __is_array_unknown_bounds
      : public __and_, __not_>>::type
    { };
    
    struct __do_is_default_constructible_impl
    {
    
      template
      static true_type __test(int,decltype(_Tp())* a = 0);
    
      template
      static false_type __test(...);
    };
    
    template
      struct __is_default_constructible_impl
      : public __do_is_default_constructible_impl
      {
        typedef decltype(__test<_Tp>(0)) type;
      };
    
    template
      struct __is_default_constructible_atom
      : public __and_<__not_>,
                      __is_default_constructible_impl<_Tp>>::type
      { };
    
    template::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
      struct __is_default_constructible_safe<_Tp, true>
      : public __and_<__is_array_known_bounds<_Tp>,
              __is_default_constructible_atom::type>>::type
      { };
    
    template
      struct __is_default_constructible_safe<_Tp, false>
      : public __is_default_constructible_atom<_Tp>::type
      { };
    } // namespace detail
    /// is_default_constructible
    template
      struct is_default_constructible
    : public integral_constant::value)>
    { };
    
    }
    

    use :

    class DefaultConstructible
    {
    public:
      DefaultConstructible() {}
    };
    
    class NotDefaultConstructible
    {
    public:
      NotDefaultConstructible(int i) {}
    };
    
    std::is_default_constructible::value // -> true
    std::is_default_constructible::value // -> false
    

提交回复
热议问题