[英]Why does std::copy() require std::back_inserter to insert into a vector with sufficient capacity?
[英]Why does std::insert require CopyConstructibility?
为什么此代码不起作用? 对于std :: map的insert方法,文档中没有关于CopyConstructibility的内容: http ://en.cppreference.com/w/cpp/container/map/insert
我可以构造std :: pair,第二个元素是我的non_copyable类,但是即使insert方法的第一个重载采用const value_type&,也无法将其插入到map中,所以应该可以正常工作。
有人可以帮助我了解为什么std :: map需要此CopyConstructibility吗?
#include <utility>
#include <map>
struct non_copyable {
non_copyable(){}
private:
non_copyable(const non_copyable&);
};
int main() {
std::pair<int, non_copyable> p; // this works!
std::map<int, non_copyable> m;
m.insert(std::pair<int, non_copyable>()); // this does NOT work
}
...即使insert方法的第一个重载采用const value_type& ,所以也可以正常工作。
不,实际上,在这种情况下,正确的过载解决方案候选对象是:
m.insert(std::pair<int, non_copyable>());
这是重载的成员函数:
template< class P >
std::pair<iterator,bool> insert( P&& value );
现在, 此页面描述了为什么它不起作用:
...仅在
std::is_constructible<value_type, P&&>::value == true
参与重载解析。
您的non_copyable
不可构造:
using M = std::map<int, non_copyable>;
using P = std::pair<int, non_copyable>;
std::is_constructible<M::value_type, P&&>::value; // false
因为没有可用的构造函数,包括由编译器生成的默认隐式move构造函数。
non_copyable
甚至禁用其默认的隐式move构造函数的原因是,由于具有用户定义的副本构造函数,如文档所述 :
如果没有为类类型(struct,class或union)提供用户定义的move构造函数,则以下所有条件均成立:
没有用户声明的副本构造函数
没有用户声明的副本分配运算符
没有用户声明的移动分配运算符
没有用户声明的析构函数
现在给non_copyable
一个move构造函数成为您的责任:
struct non_copyable {
non_copyable(){}
non_copyable(non_copyable &&) = default;
private:
non_copyable(const non_copyable&);
};
您可能会感兴趣,为什么您根本不需要制作任何副本,因此即使您可以在地图内部直接构造(成对)对,也要提供可构造副本的类型。
这是因为要提供所需的性能,通常将std :: map的内部表示形式实现为平衡的二进制搜索树(最终作为具有相似性能特征的另一个数据结构),这需要存储元素的某些特定顺序。 因此,在添加或删除某些元素之后,该顺序可能会中断,并且为了保持其正确性,有时需要存储的元素进行内部移动。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.