::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>
{
};