[C++开发经验总结]何时用push?/何时用emplace?
标题:[C++开发经验总结]何时用push?/何时用emplace?
@水墨不写bug
文章目录
- 一、push与emplace辨析
- 1. `push` 方法
- 2. `emplace` 方法
- 3. 注意事项
- 二、全文总结:
一、push与emplace辨析
1. push
方法
- 适用场景:
- 当你已经有一个对象实例,并且你想把它添加到容器中时使用。
- 语法:
push_back
:用于在容器末尾添加元素。push_front
:用于在容器开头添加元素(适用于std::deque
和std::list
)。
- 示例:
string data = "data"; vec.push_back(data); // 保留原对象,拷贝到容器 vec.push_back(std::move(data)); // 转移资源到容器
2. emplace
方法
- 适用场景:
- 当你想在容器中直接构造对象时使用,避免了不必要的临时对象创建和拷贝。
- 语法:
emplace_back
:在容器末尾直接构造对象。emplace_front
:在容器开头直接构造对象(适用于std::deque
和std::list
)。
- 示例:
std::map<int, std::string> myMap; myMap.emplace(4, "fast"); // 直接在 map 中构造 pair std::vector<std::string> vec; vec.emplace_back("direct"); // 直接构造,无临时对象
3. 注意事项
emplace
直接在容器中构造对象,通常比push
更高效,因为它避免了临时对象的创建和拷贝。- 在使用
push
时,容器需要调用拷贝构造函数或移动构造函数来添加元素。 - 需要注意,如果强制对还有用的变量
move
,那么move
后的变量会处于一种有效但未指定状态,不可依赖其内容
。
但是并不是所有的变量move之后都不可使用其内容,考虑如下的实例:
void MoveBuiltinTypes()
{
cout<<"----------------"<<endl;
std::vector<int> vec;
int a = 10;
vec.push_back(std::move(a)); // 使用push_back将已有对象a添加到容器中
cout<<"a:"<<a<<endl;
}
void MoveCustomTypes()
{
cout<<"----------------"<<endl;
std::vector<std::string> vec;
std::string s = "hello";
vec.push_back(s); // 拷贝构造:复制 s 到容器中
vec.push_back(std::move(s)); // 移动构造:转移 s 的资源到容器中
cout<<"s:"<<s<<endl;
cout<<"s.size():"<<s.size()<<endl;
}
int main()
{
MoveBuiltinTypes();
MoveCustomTypes();
return 0;
}
运行结果:
string类型的变量s在move之后,内容被清空,size被置为0;内置类型int a变量在move之后,值没有发生变化。这样是为了尽可能提高效率,string调用移动构造,把s内容交换到vec内部;而a变量不占用堆区资源,不改变a的值反而提高了效率。
于是可以推断string的移动构造类似于:
string(string&& other) noexcept {
data = other.data; // 转移指针
size = other.size;
capacity = other.capacity;
other.data = nullptr; // 原对象指针置空
other.size = 0;
other.capacity = 0;
}
二、全文总结:
(考虑占有资源的自定义类型)
push
:对象已经存在,用push。传参时候,传值调用拷贝构造,可能引发拷贝或移动开销;传引用则需要考虑是直接传引用还是传const引用。
emplace
:直接在容器内部构造对象,避免临时对象开销,性能更优。
优先使用 emplace:
当元素未构造且可直接通过参数构造时,优先使用 emplace 以提升性能。
myMap.emplace(42, "answer"); // 优于 myMap.insert({42, "answer"});
使用 push
的场景:
- 需要保留原对象(拷贝语义)。
- 需要显式移动资源(移动语义)。
- 兼容旧代码或特定接口要求。
完
转载请注明出处
/***
* .,:,,, .::,,,::.
* .::::,,;;, .,;;:,,....:i:
* :i,.::::,;i:. ....,,:::::::::,.... .;i:,. ......;i.
* :;..:::;::::i;,,:::;:,,,,,,,,,,..,.,,:::iri:. .,:irsr:,.;i.
* ;;..,::::;;;;ri,,,. ..,,:;s1s1ssrr;,.;r,
* :;. ,::;ii;:, . ................... .;iirri;;;,,;i,
* ,i. .;ri:. ... ............................ .,,:;:,,,;i:
* :s,.;r:... ....................................... .::;::s;
* ,1r::. .............,,,.,,:,,........................,;iir;
* ,s;........... ..::.,;:,,. ...............,;1s
* :i,..,. .,:,,::,. .......... .......;1,
* ir,....:rrssr;:, ,,.,::. .r5S9989398G95hr;. ....,.:s,
* ;r,..,s9855513XHAG3i .,,,,,,,. ,S931,.,,.;s;s&BHHA8s.,..,..:r:
* :r;..rGGh, :SAG;;G@BS:.,,,,,,,,,.r83: hHH1sXMBHHHM3..,,,,.ir.
* ,si,.1GS, sBMAAX&MBMB5,,,,,,:,,.:&8 3@HXHBMBHBBH#X,.,,,,,,rr
* ;1:,,SH: .A@&&B#&8H#BS,,,,,,,,,.,5XS, 3@MHABM&59M#As..,,,,:,is,
* .rr,,,;9&1 hBHHBB&8AMGr,,,,,,,,,,,:h&&9s; r9&BMHBHMB9: . .,,,,;ri.
* :1:....:5&XSi;r8BMBHHA9r:,......,,,,:ii19GG88899XHHH&GSr. ...,:rs.
* ;s. .:sS8G8GG889hi. ....,,:;:,.:irssrriii:,. ...,,i1,
* ;1, ..,....,,isssi;, .,,. ....,.i1,
* ;h: i9HHBMBBHAX9: . ...,,,rs,
* ,1i.. :A#MBBBBMHB##s ....,,,;si.
* .r1,.. ,..;3BMBBBHBB#Bh. .. ....,,,,,i1;
* :h;.. .,..;,1XBMMMMBXs,.,, .. :: ,. ....,,,,,,ss.
* ih: .. .;;;, ;;:s58A3i,.. ,. ,.:,,. ...,,,,,:,s1,
* .s1,.... .,;sh, ,iSAXs;. ,. ,,.i85 ...,,,,,,:i1;
* .rh: ... rXG9XBBM#M#MHAX3hss13&&HHXr .....,,,,,,,ih;
* .s5: ..... i598X&&A&AAAAAA&XG851r: ........,,,,:,,sh;
* . ihr, ... . .. ........,,,,,;11:.
* ,s1i. ... ..,,,..,,,.,,.,,.,.. ........,,.,,.;s5i.
* .:s1r,...................... ..............;shs,
* . .:shr:. .... ..............,ishs.
* .,issr;,... ...........................,is1s;.
* .,is1si;:,....................,:;ir1sr;,
* ..:isssssrrii;::::::;;iirsssssr;:..
* .,::iiirsssssssssrri;;:.
*/