英文:
Will copy constructor be called when calling insert of std::unordered_map
问题
以下是您要翻译的内容:
"I have a std::unordered_map and I found that the object I insert into it is different from that I got from it by using for range traversing.
I doubt that there might be some object copying happening here but after I added some dumping to the copy constructor, it is not called at all.
Could any one tell me what is happening in the background when inserting and traversing a std::unordered_map.
I tried the following code and it dumped:
[Result]
mypair constuctor
mypair constuctor
string1 address:0x7ffccb813ba0
string2 address:0x7ffccb813bd0
++++++++++++++++
auto &x address:0x55fb40529378
string2: 0.5
auto &x address:0x55fb405292c8
string1: 0.3
++++++++++++++++
auto x address:0x7ffccb813c00
string2: 0.5
auto x address:0x7ffccb813c00
string1: 0.3
++++++++++++++++
[Source]
#include <iostream>
#include <string>
#include <unordered_map>
class mypair : public std::pair<std::string,double> {
public:
mypair(std::string str, double num):std::pair<std::string,double>(str, num) {
std::cout<<"mypair constuctor"<<std::endl;
}
mypair( const mypair& ) {
std::cout<<"mypair copy constuctor"<<std::endl;
}
mypair& operator=(const mypair&) {
std::cout<<"mypair copy assignment"<<std::endl;
return *this;
}
};
int main ()
{
std::unordered_map<std::string,double> myMap;
mypair string1 ("string1", 0.3);
mypair string2 ("string2", 0.5);
std::cout << "string1 address:" << &string1 << std::endl;
std::cout << "string2 address:" << &string2 << std::endl;
std::cout <<"++++++++++++++++"<< std::endl;
myMap.insert (string1);
myMap.insert (string2);
for (auto& x: myMap) {
std::cout << "auto &x address:"<< &x << std::endl<< x.first << ": " << x.second << std::endl;
}
std::cout <<"++++++++++++++++"<< std::endl;
for (auto x: myMap) {
std::cout << "auto x address:"<< &x << std::endl<< x.first << ": " << x.second << std::endl;
}
std::cout <<"++++++++++++++++"<< std::endl;
return 0;
}
英文:
I have a std::unordered_map and I found that the object I insert into it is different from that I got from it by using for range traversing.
I doubt that there might be some object copying happening here but after I added some dumping to the copy constructor, it is not called at all.
Could any one tell me what is happening in the background when inserting and traversing a std::unordered_map.
I tried the following code and it dumped:
[Result]
mypair constuctor
mypair constuctor
string1 address:0x7ffccb813ba0
string2 address:0x7ffccb813bd0
++++++++++++++++
auto &x address:0x55fb40529378
string2: 0.5
auto &x address:0x55fb405292c8
string1: 0.3
++++++++++++++++
auto x address:0x7ffccb813c00
string2: 0.5
auto x address:0x7ffccb813c00
string1: 0.3
++++++++++++++++
[Source]
#include <iostream>
#include <string>
#include <unordered_map>
class mypair : public std::pair<std::string,double> {
public:
mypair(std::string str, double num):std::pair<std::string,double>(str, num) {
std::cout<<"mypair constuctor"<<std::endl;
}
mypair( const mypair& ) {
std::cout<<"mypair copy constuctor"<<std::endl;
}
mypair& operator=(const mypair&) {
std::cout<<"mypair copy assignment"<<std::endl;
return *this;
}
};
int main ()
{
std::unordered_map<std::string,double> myMap;
mypair string1 ("string1", 0.3);
mypair string2 ("string2", 0.5);
std::cout << "string1 address:" << &string1 << std::endl;
std::cout << "string2 address:" << &string2 << std::endl;
std::cout <<"++++++++++++++++"<< std::endl;
myMap.insert (string1);
myMap.insert (string2);
for (auto& x: myMap) {
std::cout << "auto &x address:"<< &x << std::endl<< x.first << ": " << x.second << std::endl;
}
std::cout <<"++++++++++++++++"<< std::endl;
for (auto x: myMap) {
std::cout << "auto x address:"<< &x << std::endl<< x.first << ": " << x.second << std::endl;
}
std::cout <<"++++++++++++++++"<< std::endl;
return 0;
}
答案1
得分: 5
以下是翻译好的内容:
你没有看到对mypair
的复制构造函数的任何调用,因为std::unordered_map
内部不使用该对类型。
using value_type = std::pair<const Key, Value>;
...实际上是内部使用的对类型。你的mypair
可以隐式转换为value_type
,因此应该调用以下成员函数:
template<class P>
std::pair<iterator, bool> insert(P&& value);
这既不复制也不复制分配mypair
,它将从传递的对的内容构造一个std::pair
。
如果你想尽量减少复制和开销,你应该使用emplace
或try_emplace
。
英文:
You're not seeing any calls to the copy constructor of mypair
, because that is not the pair type that the std::unordered_map
uses internally.
using value_type = std::pair<const Key, Value>;
... is the pair type that is actually used inside. Your mypair
is implicitly convertible to the value_type
, so the following member function should be called:
template< class P >
std::pair<iterator, bool> insert( P&& value );
This neither copies nor copy-assigns a mypair
, it will construct a std::pair
from the contents of the pair you pass.
If you want to minimize copying and overhead as much as possible, you should instead use emplace
or try_emplace
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论