2

::std::is_copy_constructible type trait is not 100% accurate. For example, ::std::vector<::std::unique_ptr<int> > is not copy constructible, but will be designated as such anyway by the type trait. Does there exist a way to provide a smarter copy-constructible trait, than we can find in the standard library and how, in any C++ version? The demo code has the same problem, as the standard type trait.

template <typename T, typename = void>
struct smart_cc : ::std::false_type
{
};

template <typename T>
struct smart_cc<T,
  decltype(void(T(::std::declval<T const&>())))
> : ::std::true_type
{
};

int main()
{
  ::std::cout << ::std::is_copy_constructible<::std::vector<::std::unique_ptr<int> > >{} << ::std::endl;
  ::std::cout << smart_cc<::std::unique_ptr<int> >{} << ::std::endl;
  ::std::cout << smart_cc<::std::vector<::std::unique_ptr<int> > >{} << ::std::endl;
  ::std::cout << smart_cc<int>{} << ::std::endl;

  ::std::vector<::std::unique_ptr<int> > u;
//::std::vector<::std::unique_ptr<int> > v(u);

  return 0;
}

In the end, I went with this:

template <typename T, typename = void>
struct is_copy_assignable : ::std::is_copy_assignable<T>
{
};

template <typename T>
struct is_copy_assignable<T,
  decltype(void(sizeof(typename T::value_type)))
> : is_copy_assignable<typename T::value_type>
{
};

template <typename T, typename = void>
struct is_move_assignable : ::std::is_move_assignable<T>
{
};

template <typename T>
struct is_move_assignable<T,
  decltype(void(sizeof(typename T::value_type)))
> : is_move_assignable<typename T::value_type>
{
};

template <typename T, typename = void>
struct is_copy_constructible : ::std::is_copy_constructible<T>
{
};

template <typename T>
struct is_copy_constructible<T,
  decltype(void(sizeof(typename T::value_type)))
> : is_copy_constructible<typename T::value_type>
{
};

template <typename T, typename = void>
struct is_move_constructible : ::std::is_move_constructible<T>
{
};

template <typename T>
struct is_move_constructible<T,
  decltype(void(sizeof(typename T::value_type)))
> : is_move_constructible<typename T::value_type>
{
};
user1095108
  • 14,119
  • 9
  • 58
  • 116

0 Answers0