C++ Smarter可用于处理集装箱

C++ Smarter可用于处理集装箱,c++,templates,sfinae,typetraits,C++,Templates,Sfinae,Typetraits,我正在尝试编写自己版本的std::is_copy_constructible,对于仅移动类型的容器将返回false 我已经找到了描述如何为特定容器类型实现这一点的方法。现在,我试图将其扩展到适用于任何容器。出于我的目的,我将“容器”定义为具有“value\u type”成员的任何类。为了确定一个类是否有“value\u type”成员,我在这个类上使用了一个变量 所以我现在基本上是这样的: template <typename T, typename = void> struct h

我正在尝试编写自己版本的std::is_copy_constructible,对于仅移动类型的容器将返回false

我已经找到了描述如何为特定容器类型实现这一点的方法。现在,我试图将其扩展到适用于任何容器。出于我的目的,我将“容器”定义为具有“value\u type”成员的任何类。为了确定一个类是否有“value\u type”成员,我在这个类上使用了一个变量

所以我现在基本上是这样的:

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 {};
模板
结构具有_值_类型:std::false_类型{};
模板
结构具有_值_类型:std::true_类型{};
用于确定类是否具有值\类型成员,以及:

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>;
模板
结构智能测试:测试{};
模板
结构智能测试:智能测试{};
模板
使用smart\u是可复制的=smart\u测试;
对于定义smart_,它是可构造的,可正确用于向量和非容器类型

我想将两者结合起来创建一个版本的smart_is_copy_constructible,它可以正确地用于所有容器类型(具有值类型成员的类型)。我怀疑我需要使用std::enable_if和has_value_type struct以某种方式实现这一点,但这是我第一次尝试模板元编程,我不确定如何继续

到目前为止,我最好的猜测是试试这个

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> {};
模板

结构智能测试Yes,
std::enable\u如果t
可以:

// I'd recommend following the standard library's naming convention
template<typename T, typename = void>
struct smart_is_copy_constructible : std::is_copy_constructible<T> { };
template<typename T>
struct smart_is_copy_constructible<T, std::enable_if_t<has_value_type<T>::value>> : std::is_copy_constructible<typename T::value_type> { };

template<typename T>
constexpr bool smart_is_copy_constructible_v = smart_is_copy_constructible<T>::value;

(第一个示例中使用的校正后的
具有_值_类型

template <typename T, typename = void>
struct has_value_type : std::false_type {};
template <typename T>
struct has_value_type<T, std::void_t<typename T::value_type>> : std::true_type {};
模板
结构具有_值_类型:std::false_类型{};
模板
结构具有_值_类型:std::true_类型{};

)

FYI:第一个代码块中的
decltype
mess可以替换为
std::void\t
。事实上,如文中所述,它不起作用
value\u type
是一个类型成员,它作为一个表达式(出现在
左侧)没有意义。“出于我的目的,我将“容器”定义为具有“value\u type”成员的任何类。”仅供参考:迭代器通常将
value\u type
作为成员,非容器类型如
string\u视图
span
。这可能不是一条很好的界限。
template <typename T, typename = void>
struct has_value_type : std::false_type {};
template <typename T>
struct has_value_type<T, std::void_t<typename T::value_type>> : std::true_type {};