蘭州網(wǎng)站做的好點(diǎn)的公司網(wǎng)站制作廠家有哪些
C++11的新特性可變參數(shù)模板能夠創(chuàng)建可以接受可變參數(shù)的函數(shù)模板和類模板,相比C++98/03,類模版和函數(shù)模版中只能含固定數(shù)量的模版參數(shù),可變模版參數(shù)無疑是一個(gè)巨大的改進(jìn)。然而由于可變模版參數(shù)比較抽象,使用起來需要一定的技巧,所以這塊還是比較晦澀的。
1. 函數(shù)模板
下面就是一個(gè)基本可變參數(shù)的函數(shù)模板,Args是一個(gè)模板參數(shù)包,args是一個(gè)函數(shù)形參參數(shù)包,聲明一個(gè)參數(shù)包Args...args,這個(gè)參數(shù)包中可以包含0到任意個(gè)模板參數(shù)。
template <class ...Args>
void ShowList(Args... args)
{}
上面的參數(shù)args前面有省略號(hào),所以它就是一個(gè)可變模版參數(shù),我們把帶省略號(hào)的參數(shù)稱為“參數(shù) 包”,它里面包含了0到N(N>=0)個(gè)模版參數(shù)。我們無法直接獲取參數(shù)包args中的每個(gè)參數(shù)的, 只能通過展開參數(shù)包的方式來獲取參數(shù)包中的每個(gè)參數(shù),這是使用可變模版參數(shù)的一個(gè)主要特點(diǎn),也是最大的難點(diǎn),即如何展開可變模版參數(shù)。由于語法不支持使用args[i]這樣方式獲取可變參數(shù),所以我們的用一些奇招來一一獲取參數(shù)包的值。
2.遞歸函數(shù)方式展開參數(shù)包
// 遞歸終止函數(shù)
template<class T>
void ShowList(T value)
{cout << value << endl;}
// 展開函數(shù)
template<class T,class ...Args>
void ShowList(T value,Args ... args)
{cout << value << " ";ShowList(args...);
}
int main()
{ShowList(1);ShowList(1,'a');ShowList(1,'a',"abcde");return 0;
}
3.逗號(hào)表達(dá)式展開參數(shù)包
template<class T>
void PrintArg(T value)
{cout << value << " ";
}
// 展開函數(shù)
template<class ...Args>
void ShowList(Args ... args)
{int arr[] = { (PrintArg(args),0)... };cout << endl;
}
int main()
{ShowList(1);ShowList(1,'a');ShowList(1,'a',"abcde");return 0;
}
這種展開參數(shù)包的方式,不需要通過遞歸終止函數(shù),是直接在函數(shù)體中展開的, PrintArg 不是一個(gè)遞歸終止函數(shù),只是一個(gè)處理參數(shù)包中每一個(gè)參數(shù)的函數(shù)。這種就地展開參數(shù)包的方式實(shí)現(xiàn)的關(guān)鍵是逗號(hào)表達(dá)式。我們知道逗號(hào)表達(dá)式會(huì)按順序執(zhí)行逗號(hào)前面的表達(dá)式。 ShowList函數(shù)中的逗號(hào)表達(dá)式:(PrintArg(args), 0),也是按照這個(gè)執(zhí)行順序,先執(zhí)行 PrintArg(args),再得到逗號(hào)表達(dá)式的結(jié)果0。同時(shí)還用到了C++11的另外一個(gè)特性——初始化列表,通過初始化列表來初始化一個(gè)變長數(shù)組, {(PrintArg(args), 0)...}將會(huì)展開成((PrintArg(arg1),0), (PrintArg(arg2),0), (PrintArg(arg3),0), etc... ),最終會(huì)創(chuàng)建一個(gè)元素值都為0的數(shù)組int arr[sizeof...(Args)]。由于是逗號(hào)表達(dá)式,在創(chuàng)建數(shù)組的過程中會(huì)先執(zhí)行逗號(hào)表達(dá)式前面的部分printarg(args) 打印出參數(shù),也就是說在構(gòu)造int數(shù)組的過程中就將參數(shù)包展開了,這個(gè)數(shù)組的目的純粹是為了在數(shù)組構(gòu)造的過程展開參數(shù)包
4.STL容器中的empalce相關(guān)接口函數(shù)
template <class... Args>
void emplace_back (Args&&... args);
首先我們看到的emplace系列的接口,支持模板的可變參數(shù),并且萬能引用。
int main()
{// emplace_back支持可變參數(shù),拿到構(gòu)建pair對象的參數(shù)后自己去創(chuàng)建對象list<pair<string, int>> l;l.emplace_back(make_pair( "aaa", 1 ));l.emplace_back("bbb", 2);// push_back支持初始化列表傳參l.push_back(make_pair("ccc", 3));l.push_back({ "ddd",4 });return 0;
}
那么在這里我們可以看到除了用法上,似乎和push_back沒什么太大的區(qū)別,實(shí)際上,emplace_back優(yōu)勢更大。
減少不必要的復(fù)制或移動(dòng)操作
emplace_back
函數(shù)利用完美轉(zhuǎn)發(fā)技術(shù),直接在容器內(nèi)部構(gòu)造元素,從而避免了創(chuàng)建臨時(shí)對象后再進(jìn)行復(fù)制或移動(dòng)的開銷。這對于構(gòu)造成本較高的對象尤為重要,因?yàn)樗梢詼p少額外的資源消耗和性能損失.?