東至網(wǎng)站定制免費入駐的賣貨平臺
👍作者主頁:進(jìn)擊的1++
🤩 專欄鏈接:【1++的C++進(jìn)階】
在前面C++11系列的文章里,我們漏掉了幾個知識點,這篇文章對其中一個知識點進(jìn)行講解,關(guān)于剩余的知識點的文章在后面會相繼出爐。
C++11中,針對順序容器(如vector、deque、list),新標(biāo)準(zhǔn)引入了三個新成員:emplace_front、emplace和emplace_back,這些操作構(gòu)造而不是拷貝元素。這三個操作與push_front,insert,push_back操作相同。
下面我們以vector為例對emplace進(jìn)行講解。
通過上面兩幅圖的比較,我們可以看出其用法與insert較為一致,只是在第一個參數(shù)之后較為不同,emplace第一個參數(shù)后的Arg&& …args 參數(shù)包是指什么呢?
可以簡單理解為就是其插入元素的構(gòu)造函數(shù)需要多少參數(shù),其就應(yīng)該傳多少參數(shù)。
其用法如下:
class B
{
public:B(int a,int b):_a(a),_b(b){}private:int _a;int _b;
};
void test1()
{vector<B> v1;v1.insert(v1.begin(),B(1, 2));v1.emplace(v1.begin(), 1, 3);
}
那么,既然emplace的用法與insert相似,為什么C++11中要增加它呢?
其區(qū)別是什么?
我們用下面的代碼進(jìn)行驗證:
class B
{
public:B(int a,int b):_a(a),_b(b){cout << "構(gòu)造函數(shù)" << endl;}B(const B& b):_a(b._a), _b(b._b){cout << "拷貝構(gòu)造" << endl;}B(const B&& b):_a(b._a), _b(b._b){cout << "移動構(gòu)造" << endl;}B& operator=(const B& b) = default;//當(dāng)我們顯式構(gòu)造了移動構(gòu)造//編譯器就不會在生成默認(rèn)拷貝構(gòu)造和移動賦值
private:int _a;int _b;
};void test2()
{vector<B> v1;v1.insert(v1.begin(), B(1, 2));cout << "/" << endl;vector<B> v2;v2.emplace(v2.begin(), 1, 3);
}
通過運行結(jié)果我們可以發(fā)現(xiàn),insert在插入時,由于我們傳的是右值,其調(diào)用了構(gòu)造和移動構(gòu)造,而emplace只調(diào)用了構(gòu)造函數(shù)。也就是說,emplace是在插入位置直接構(gòu)造元素,而不是和insert一樣,先是構(gòu)造好,再移動或復(fù)制到插入位置。這樣做的優(yōu)勢就是能夠減少一次移動構(gòu)造或拷貝構(gòu)造。