c++ - 更智能的 is_copy_constructible 用于处理容器
问题描述
我正在尝试编写我自己的 std::is_copy_constructible 版本,它将为仅移动类型的容器返回 false 。
我已经找到了这个答案,描述了如何使它适用于特定的容器类型。现在我正在尝试将其扩展为适用于任何容器。出于我的目的,我将“容器”定义为任何具有“value_type”成员的类。为了确定一个类是否有“value_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 {};
用于确定一个类是否具有 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 {};
)
推荐阅读
- node.js - 安装 react-native-elements 时出现 NPM 错误
- javascript - 有没有办法在 javaScript 或 jQuery 或剑道网格中将“nb-NO”小数转换为“en-US”
- javascript - 为什么在这个循环中倒计时顺序会发生变化?
- android - 如何在 Google Play 管理中心设置“广告”设置
- html - 防止我的图像在较小尺寸的屏幕上出现在我的 div 后面
- npm - 使用 npm 安装 expo cli 不起作用
- kubernetes - kubectl 编辑部署不工作,但 kubectl 应用在设置资源请求/限制部署时工作
- mongodb - MongoDB 指南针参考
- javascript - 如何在 Nuxt Config 中使用 Firebase 环境变量
- c++ - 当数据包长度或多或少时 async_read 出现问题