C++11容器中新增加的emplace相关函数的使用
C++11中,針對順序容器(如vector、deque、list),新標準引入了三個新成員:emplace_front、emplace和emplace_back,這些操作構造而不是拷貝元素。這些操作分別對應push_front、insert和push_back,允許我們將元素放置在容器頭部、一個指定位置之前或容器尾部。
當調用push或insert成員函數時,我們將元素類型的對象傳遞給它們,這些對象被拷貝到容器中。而當我們調用一個emplace成員函數時,則是將參數傳遞給元素類型的構造函數。emplace成員使用這些參數在容器管理的內存空間中直接構造元素。
emplace函數的參數根據元素類型而變化,參數必須與元素類型的構造函數相匹配。emplace函數在容器中直接構造元素。傳遞給emplace函數的參數必須與元素類型的構造函數相匹配。
其它容器中,std::forward_list中的emplace_after、emplace_front函數,std::map/std::multimap中的emplace、emplace_hint函數,std::set/std::multiset中的emplace、emplace_hint,std::stack中的emplace函數,等emplace相似函數操作也均是構造而不是拷貝元素。
emplace相關函數可以減少內存拷貝和移動。當插入rvalue,它節約了一次move構造,當插入lvalue,它節約了一次copy構造。
下面是從其他文章中copy的測試代碼,詳細內容介紹可以參考對應的reference:
#include "emplace.hpp"
#include <iostream>
#include <vector>
#include <string>
#include <map>
#include <tuple>
#include <utility>namespace emplace_ {/
// reference: http://www.cplusplus.com/reference/vector/vector/emplace_back/
int test_emplace_1()
{
{/*template <class... Args>void emplace_back (Args&&... args);*/std::vector<int> myvector = { 10, 20, 30 };myvector.emplace_back(100);myvector.emplace_back(200);std::cout << "myvector contains:";for (auto& x : myvector)std::cout << ' ' << x;std::cout << '\n';
}{/*template <class... Args>iterator emplace (const_iterator position, Args&&... args);*/std::vector<int> myvector = { 10, 20, 30 };auto it = myvector.emplace(myvector.begin() + 1, 100);myvector.emplace(it, 200);myvector.emplace(myvector.end(), 300);std::cout << "myvector contains:";for (auto& x : myvector)std::cout << ' ' << x;std::cout << '\n';
}return 0;
}///
// reference: http://en.cppreference.com/w/cpp/container/vector/emplace_back
namespace {
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 test_emplace_2()
{/*The following code uses emplace_back to append an object of type President to a std::vector.It demonstrates how emplace_back forwards parameters to the President constructor and showshow using emplace_back avoids the extra copy or move operation required when using push_back.*/std::vector<President> elections;std::cout << "emplace_back:\n";elections.emplace_back("Nelson Mandela", "South Africa", 1994);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";}return 0;
}// reference: https://stackoverflow.com/questions/4303513/push-back-vs-emplace-back
int test_emplace_3()
{/*template <class... Args>pair<iterator,bool> emplace (Args&&... args);*/typedef std::tuple<int, double, std::string> Complicated;std::map<int, Complicated> m;int anInt = 4;double aDouble = 5.0;std::string aString = "C++";// cross your finger so that the optimizer is really good//m.insert(/*std::make_pair*/std::pair<int, Complicated>(4, Complicated(anInt, aDouble, aString)));m.insert(std::make_pair(4, Complicated(anInt, aDouble, aString)));// should be easier for the optimizerm.emplace(6, Complicated(anInt, aDouble, aString));/*std::piecewise_construct: This constant value is passed as the first argument to construct a pair objectto select the constructor form that constructs its members in place by forwarding the elements of twotuple objects to their respective constructor.*/m.emplace(std::piecewise_construct, std::make_tuple(8), std::make_tuple(anInt, aDouble, aString));return 0;
}//
// reference: https://corecplusplustutorial.com/difference-between-emplace_back-and-push_back-function/
namespace {
class Dat {int i;std::string ss;char c;public:Dat(int ii, std::string s, char cc) :i(ii), ss(s), c(cc) { }~Dat() { }
};
}int test_emplace_4()
{std::vector<Dat> vec;vec.reserve(3);vec.push_back(Dat(89, "New", 'G')); // efficiency lesser//vec.push_back(678, "Newer", 'O'); // error,push_back can’t accept three argumentsvec.emplace_back(890, "Newest", 'D'); // work fine, efficiency is also morereturn 0;
}} // namespace emplace_
GitHub: https://github.com/fengbingchun/Messy_Test??
總結
以上是生活随笔為你收集整理的C++11容器中新增加的emplace相关函数的使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: TEE(Trusted Executio
- 下一篇: C++11多线程中std::call_o