push_back还是emplace_back?
生活随笔
收集整理的這篇文章主要介紹了
push_back还是emplace_back?
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
背景和區別
emplace_back()?是?C++11?之后,vector容器中添加的新方法,和?push_back()一樣,都是在容器末尾添加一個新的元素,相對于push_back函數,它減少了一次類的構造。不同的是emplace_back()?在效率上相比較于?push_back()?有了一定的提升。
廢話不多說,上經典代碼:
#include <vector> #include <string> #include <cassert> #include <iostream>struct President {std::string name;std::string country;int year;President(std::string p_name, std::string p_country, int p_year): name(std::move(p_name)), country(std::move(p_country)), year(p_year){std::cout << "I am being constructed.\n";}President(President&& other): name(std::move(other.name)), country(std::move(other.country)), year(other.year){std::cout << "I am being moved.\n";}President& operator=(const President& other) = default; };int main() {std::vector<President> elections;std::cout << "emplace_back:\n";auto& ref = elections.emplace_back("Nelson Mandela", "South Africa", 1994);assert(ref.year == 1994 && "uses a reference to the created object (C++17)");std::vector<President> reElections;std::cout << "\npush_back:\n";reElections.push_back(President("Franklin Delano Roosevelt", "the USA", 1936));std::cout << "\nContents:\n";for (President const& president: elections) {std::cout << president.name << " was elected president of "<< president.country << " in " << president.year << ".\n";}for (President const& president: reElections) {std::cout << president.name << " was re-elected president of "<< president.country << " in " << president.year << ".\n";} }看運行結果:
emplace_back: I am being constructed.push_back: I am being constructed. I am being moved.Contents: Nelson Mandela was elected president of South Africa in 1994. Franklin Delano Roosevelt was re-elected president of the USA in 1936.push_back()向容器中加入一個右值元素(臨時對象)的時候,首先會調用構造函數構造這個臨時對象,然后需要調用拷貝構造函數將這個臨時對象放入容器中。原來的臨時變量釋放。這樣造成的問題是臨時變量申請的資源就浪費。
emplace_back()?函數在原理上比?push_back()?有了一定的改進,包括在內存優化方面和運行效率方面。內存優化主要體現在使用了就地構造(直接在容器內構造對象,不用拷貝一個復制品再使用)+強制類型轉換的方法來實現,在運行效率方面,由于省去了拷貝構造過程,因此也有一定的提升。
emplace_back能完全代替push_back嗎?
std::vector<std::vector<int>> v; v.push_back({1,2,3}); // OK v.emplace_back({1,2,3}); // error v.emplace_back(std::vector<int>{1,2,3}); // OK v.emplace_back<std::vector<int>>({1,2,3}); // OK std::vector<std::regex> v; v.push_back(nullptr); // 編譯出錯 v.emplace_back(nullptr); // 通過編譯,但運行時拋出異常并且難以定位 創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的push_back还是emplace_back?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 观察者模式和js自定义事件
- 下一篇: 【NLP】为元宇宙拼了?FaceBook