调用 std::unordered_map 的插入时会调用复制构造函数吗

Will copy constructor be called when calling insert of std::unordered_map

提问人:Chansy 提问时间:7/6/2023 最后编辑:sebo1234Chansy 更新时间:7/6/2023 访问量:83

问:

我有一个 std::unordered_map,我发现我插入其中的对象与我通过用于范围遍历从中得到的对象不同。

我怀疑这里可能会发生一些对象复制,但是在我向复制构造函数添加一些转储之后,它根本没有被调用。

谁能告诉我插入和遍历 std::unordered_map 时后台发生了什么。

我尝试了以下代码,它转储了:

[结果]

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
++++++++++++++++

[查看模板]

#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;
}
C++ stl 复制构造函数 无序映射

评论

0赞 Gerhardh 7/6/2023
请不要添加多种语言标签,除非您想同时使用这两种语言标签,或者您询问差异。似乎没有什么与C语言有关的东西。
0赞 Alan Birtles 7/6/2023
您不是在插入地图,而是在复制其值,这就是为什么您看不到任何打印件的原因mypair
0赞 François Andrieux 7/6/2023
这是对象切片的情况。 按值使用。如果尝试使用派生自的类型,则映射将仅复制其中的一部分并“切掉对象的其余部分”。std::unordered_mapstd::pairstd::pairstd::pair

答:

5赞 Jan Schultke 7/6/2023 #1

您没有看到对 的复制构造函数的任何调用,因为这不是内部使用的对类型。mypairstd::unordered_map

using value_type = std::pair<const Key, Value>;

...是内部实际使用的对类型。Your 是隐式可转换为 的,因此应调用以下成员函数:mypairvalue_type

template< class P >
std::pair<iterator, bool> insert( P&& value );

这既不复制也不复制分配 a ,它将从您传递的对的内容中构造 a。mypairstd::pair

如果要尽可能减少复制和开销,则应改用 或 。emplacetry_emplace