I'm trying to write my own version of std::is_copy_constructible that will return false for containers of move-only types.
I already found this answer describing how to make this work for a specific container type. Now I'm trying to expand that to work for any Container. For my purposes I am defining "Container" to mean any class that has a 'value_type' member. To determine whether or not a class has a 'value_type' member, I am using a variant on this this answer.
So basically what I have right now is this:
template <typename T, typename = void>
struct has_value_type : std::false_type {};
template <typename T>
struct has_value_type<T, decltype(std::declval<T>().value_type, void())> : std::true_type {};
for determining whether a class has a value_type member, and this:
template <template <typename> class test, typename T>
struct smart_test : test<T> {};
template <template <typename> class test, typename T, typename A>
struct smart_test<test, std::vector<T, A>> : smart_test<test, T> {};
template <typename T>
using smart_is_copy_constructible = smart_test<std::is_copy_constructible, T>;
for defining smart_is_copy_constructible that works correctly for vectors and non-container types.
I want to combine the two to create a version of smart_is_copy_constructible that works correctly for all container types (types with a value_type member). I suspect I need to use std::enable_if with my has_value_type struct in some way to do this, but this is my first foray into template metaprogramming and I'm not sure how to proceed.
My best guess so far was to try this
template <template <typename> class test, typename T>
struct smart_test<test, std::enable_if_t<has_value_type<T>::value> : smart_test<test, typename T::value_type> {};
Instead of the second declaration from the previous code block (the one defining a version of smart_test specialized on vector), but this fails to compile.
Any help would be greatly appreciated!