在我的 clang 和 libc++ 版本中(接近HEAD
), this static_assert
passes:
static_assert(std::is_copy_constructible_v<std::vector<std::unique_ptr<int>>>)
当然,如果您实际上尝试复制构造唯一指针的向量,它将无法编译:
../include/c++/v1/__memory/allocator.h:151:28: error: call to implicitly-deleted copy constructor of 'std::unique_ptr<int>'
::new ((void*)__p) _Up(_VSTD::forward<_Args>(__args)...);
[...]
note: in instantiation of member function 'std::vector<std::unique_ptr<int>>::vector' requested here
const std::vector<std::unique_ptr<int>> bar(foo);
^
../include/c++/v1/__memory/unique_ptr.h:215:3: note: copy constructor is implicitly deleted because 'unique_ptr<int>' has a user-declared move constructor
unique_ptr(unique_ptr&& __u) _NOEXCEPT
我认为这种情况是因为std::vector<T>
实现不使用 SFINAE 来禁用复制构造函数T
不可复制构造。但为什么不呢?标准中是否有规定必须以这种方式工作?这是不幸的,因为这意味着我自己的围绕复制构造性的 SFINAE 并没有在向量方面做正确的事情。
std::vector
和其他容器(除了std::array
) 被指定有一个复制构造函数。这并未指定为以元素类型是否可复制为条件。如果元素类型不可复制,则仅禁止复制构造函数定义的实例化。
因此std::is_copy_constructible_v
容器上永远是true
。无法测试定义的实例化是否具有类型特征的格式良好。
如果元素类型不可复制,则可以指定不声明复制构造函数或将其排除在重载解析之外。然而,这会带来一个权衡,这篇博文详细解释了这一点:https://quuxplusone.github.io/blog/2020/02/05/vector-is-copyable- except-when-its-not/ https://quuxplusone.github.io/blog/2020/02/05/vector-is-copyable-except-when-its-not/.
简而言之,如果我们希望能够使用不完整类型的容器,例如递归地喜欢
struct X {
std::vector<X> x;
};
那么我们无法确定是否X
当容器类实例化时是可复制的。因此,复制构造函数的声明不能依赖于此属性。
自 C++17 起,该标准要求std::vector
, std::list
and std::forward_list
,但不是其他容器,可以像这样处理不完整的类型。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)