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