C++ emplace_back


在C++開發過程中,我們經常會用STL的各種容器,比如vector,map,set等,這些容器極大的方便了我們的開發。在使用這些容器的過程中,我們會大量用到的操作就是插入操作,比如vector的push_back,map的insert,set的insert。這些插入操作會涉及到兩次構造,首先是對象的初始化構造,接着在插入的時候會復制一次,會觸發拷貝構造。但是很多時候我們並不需要兩次構造帶來效率的浪費,如果可以在插入的時候直接構造,就只需要構造一次就夠了。

C++11標准已經有這樣的語法可以直接使用了,那就是emplace。vector有兩個函數可以使用:emplace,emplace_back。emplace類似insert,emplace_back類似push_back。通過示例代碼可以更清晰的了解到他們的區別。

[cpp] view plain copy
// Book結構,保存書本信息
struct SBook
{
SBook() : bookName(""), price(0)
{
std::cout << "default construct: " << bookName << std::endl;
}
SBook(std::string bookName_, int price_) : bookName(bookName_), price(price_)
{
std::cout << "construct: " << bookName << std::endl;
};
SBook(SBook& rhs) : bookName(rhs.bookName), price(rhs.price)
{
std::cout << "copy construct: " << bookName << std::endl;
}
~SBook()
{
std::cout << "deconstruct: " << bookName << std::endl;
}

bool operator <(const SBook& rhs) const
{
return bookName < rhs.bookName;
}
std::string bookName;
int price;
};
// 測試vector
vector books;
// 預先分配,否則整個vector在容量不夠的情況下重新分配內存
books.reserve(100);

std::cout << "test push_back:" << endl;
books.push_back(SBook("C++從入門到放棄", 1));
std::cout << endl;

std::cout << "test emplace_back:" << endl;
books.emplace_back("水滸傳", 2);
std::cout << endl;

std::cout << "test emplace_back default:" << endl;
books.emplace_back();
auto& book = books.back();
book.bookName = "紅樓夢";
book.price = 5;
std::cout << endl;

std::cout << "test emplace:" << endl;
auto it = books.emplace(books.end());
it->bookName = "西游記";
it->price = 3;
std::cout << endl;

std::cout << "output all books: " << endl;
for_each(books.begin(), books.end(), [](const SBook& book)->void
{
std::cout << book.bookName << endl;
});
std::cout << endl;​
​​

// 測試set
set bookSet;​

std::cout << "test bookSet insert:" << endl;
bookSet.insert(SBook("十萬個為什么", 1));
std::cout << endl;

​std::cout<< "test bookSet emplace:" << endl;
bookSet.emplace("新華字典", 2);
std::cout << endl;

​std::cout<< "output bookset: " << endl;
for_each(bookSet.begin(), bookSet.end(), [](const SBook&book)->void
{
std::cout << book.bookName << endl;
});
std::cout << endl;

運行結果如下

從結果可以看出,books.push_back(SBook("C++從入門到放棄",1)) 這個語句首先執行了構造函數,接着執行拷貝構造復制到vector,最后銷毀臨時對象。
而emplace_back和emplace都只調用一次構造函數。兩相對比,效率上的提高不言而喻。

set的分析結果也類似,bookSet.insert(SBook("十萬個為什么",1)) 這個語句執行了兩次構造,一次析構。而 bookSet.emplace("新華字典", 2) 語句只執行了一次構造。

通過上面的分析,在開發過程中,如果使用emplace可以達到效果,就應該盡量使用emplace。尤其像push_back,insert這種大量使用的語句,替換使用可以從整體上提高程序的運行效率。

總結相關語法如下
vector
emplace <-> insert
emplace_back​ <-> ​push_back

set
emplcace <-> insert

map
emplace <-> insert


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM