在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
// 預先分配,否則整個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
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
