提问人:StoneThrow 提问时间:10/16/2022 更新时间:10/16/2022 访问量:83
当 insert() 插入到 std::map 中时,为什么 copy-contructor 被调用两次?
When insert()ing into a std::map why is the copy-contructor called twice?
问:
为什么在此代码中调用了两次复制构造函数?
// main.cpp
#include <iostream>
#include <map>
#include <string>
using namespace std;
class C {
private:
int i_;
char c_;
public:
C(int i, char c) : i_(i), c_(c) { cout << "ctor" << endl; }
C(const C& other) { cout << "copy-ctor" << endl; }
};
int main(int argc, char* argv[]) {
map<string, C> m;
m.insert({"hello", C(42, 'c')});
return 0;
}
构建和输出:
$ g++ --version && g++ -g ./main.cpp && ./a.out
g++ (Debian 6.3.0-18+deb9u1) 6.3.0 20170516
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
ctor
copy-ctor
copy-ctor
答:
3赞
273K
10/16/2022
#1
映射值类型为 。 不可移动,因此不可移动。std::pair<const int, C>
C
std::pair<const int, C>
m.insert({"hello", C(42, 'c')});
创建 并将其复制到 中的局部变量,然后将 复制到地图存储桶。C
pair
value
insert
pair
m.emplace("hello", C(42, 'c'));
将仅复制一次到存储桶。C
Compiler options...
Program returned: 0
Program stdout
ctor
copy-ctor
评论
1赞
JeJo
10/16/2022
如果 emplace 使用正确,则根本不会有任何副本:gcc.godbolt.org/z/P6MEfjnsfm.emplace( std::piecewise_construct, std::forward_as_tuple("hello"), std::forward_as_tuple(42, 'c') );
0赞
273K
10/16/2022
@JeJo 是的,我看到了你对这个问题的精彩评论,但我没有时间向 OP 解释。
评论
std::map::emplace
m.emplace( std::piecewise_construct, std::forward_as_tuple("hello"), std::forward_as_tuple(42, 'c') );
this
cout << "ctor: " << this << endl;
cout << "copy-ctor " << this << endl;