C++ 为什么map.insert()方法调用复制构造函数两次?
我正在创建自定义类C++ 为什么map.insert()方法调用复制构造函数两次?,c++,map,copy-constructor,C++,Map,Copy Constructor,我正在创建自定义类节点,以便使用映射容器实现二叉树:映射的int键是节点对象的标识符。在类节点中我必须实现一个复制构造函数 在地图上插入节点对象时,我注意到节点的复制构造函数被调用了两次。为什么? cout << "node2" << endl; Node node2; node2.set_depth(2); node2.make_it_branch(3,4); cout << "map" << endl; map<int,Node>
节点
,以便使用映射
容器实现二叉树:映射的int
键是节点
对象的标识符。在类节点中
我必须实现一个复制构造函数
在地图上插入节点
对象时,我注意到节点
的复制构造函数被调用了两次。为什么?
cout << "node2" << endl;
Node node2;
node2.set_depth(2);
node2.make_it_branch(3,4);
cout << "map" << endl;
map<int,Node> mapping;
cout << "toInsert" << endl;
pair<int,Node> toInsert = pair<int,Node>(2,node2);
cout << "insert" << endl;
mapping.insert(toInsert);
很可能是因为映射的值类型是
pair
,而不是pair
:在映射中,键是常量
由于insert()
接受对常量&
,并且您提供了对
,因此必须构造一个临时变量来执行转换,然后才能从中复制构造映射中的值
要验证它,请更改此行:
pair<int, Node> toInsert = pair<int, Node>(2, node2);
pair<int const, Node> toInsert = pair<int const, Node>(2, node2);
pair-toInsert=pair(2,节点2);
进入这一行:
pair<int, Node> toInsert = pair<int, Node>(2, node2);
pair<int const, Node> toInsert = pair<int const, Node>(2, node2);
pair-toInsert=pair(2,节点2);
您应该看到对复制构造函数的额外调用消失了
还请记住,标准库容器的具体实现不需要执行特定数量的副本:实现可能会有所不同,不同的优化级别也会使事情有所不同。执行以下操作时:
toInsert = pair<int, Node>(2, node2);
。。是的,您是通过引用传递的,但是容器不知道所引用对象的生存期(toInsert
)。因此,它将自己的副本存储在容器中。复制#2。您正在使用的是配对
。
insert方法采用的类型是map::value\u type
,定义为pair
。
编译器必须插入额外的副本才能在这两种类型之间转换
尝试使用map::value\u type
而不是pair
。最好使用类本身定义的类型,而不是从头开始重新创建它们
你也可以通过写作来避免你的第一份
map<int,Node>::value_type toInsert(2,node2);
map::value\u type to插入(2,节点2);
而不是
map<int,Node>::value_type toInsert = map<int,Node>::value_type(2,node2);
map::value\u type to insert=map::value\u type(2,节点2);
您的解释中副本3在哪里?OP的帖子显示了一份toInsert(您解释过),两份insert(您只解释过一份)。另外,我认为你对第二部分的解释不正确。容器复制并插入它们的原因是出于设计(即,它们承诺这样做,以便插入范围中的对象保持不变),而不是因为生命周期的原因。如果你不想这样,你可以使用emplace
或std::move
。有趣的是,我似乎误解了这个问题。嗯,我现在也从公认的答案中学到了一些东西。哦,好吧。