更智能 is_copy_constructible 处理容器
Smarter is_copy_constructible for handling Containers
我正在尝试编写我自己的 std::is_copy_constructible 版本,对于仅移动类型的容器 return false。
我已经找到 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。
基本上我现在拥有的是:
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 {};
用于判断一个class是否有一个value_type成员,这个:
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_is_copy_constructible 可正确用于向量和非容器类型。
我想将两者结合起来创建一个适用于所有容器类型(具有 value_type 成员的类型)的 smart_is_copy_constructible 版本。我怀疑我需要以某种方式将 std::enable_if 与我的 has_value_type 结构一起使用,但这是我第一次涉足模板元编程,我不确定如何进行。
到目前为止我最好的猜测是试试这个
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> {};
而不是前一个代码块中的第二个声明(定义 smart_test 专门针对向量的版本),但是编译失败。
如有任何帮助,我们将不胜感激!
是的,std::enable_if_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;
但 has_value_type
多半是多余的。你的实现不起作用,我在评论中给出的实现足够短,可以内联(不过,正如 Nicol Bolas 所建议的,你可能想让 has_value_type
更复杂):
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::void_t<typename T::value_type>> : std::is_copy_constructible<typename T::value_type> { };
(第一个示例中使用的更正 has_value_type
是
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::is_copy_constructible 版本,对于仅移动类型的容器 return false。
我已经找到 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。
基本上我现在拥有的是:
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 {};
用于判断一个class是否有一个value_type成员,这个:
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_is_copy_constructible 可正确用于向量和非容器类型。
我想将两者结合起来创建一个适用于所有容器类型(具有 value_type 成员的类型)的 smart_is_copy_constructible 版本。我怀疑我需要以某种方式将 std::enable_if 与我的 has_value_type 结构一起使用,但这是我第一次涉足模板元编程,我不确定如何进行。
到目前为止我最好的猜测是试试这个
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> {};
而不是前一个代码块中的第二个声明(定义 smart_test 专门针对向量的版本),但是编译失败。
如有任何帮助,我们将不胜感激!
是的,std::enable_if_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;
但 has_value_type
多半是多余的。你的实现不起作用,我在评论中给出的实现足够短,可以内联(不过,正如 Nicol Bolas 所建议的,你可能想让 has_value_type
更复杂):
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::void_t<typename T::value_type>> : std::is_copy_constructible<typename T::value_type> { };
(第一个示例中使用的更正 has_value_type
是
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 {};
)