最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

淺析C++模板類型中的原樣轉(zhuǎn)發(fā)和可變參數(shù)的實現(xiàn)

 更新時間:2022年08月09日 15:49:57   作者:戀戀風(fēng)辰  
可變參數(shù)模板(variadic templates)是C++11新增的強大的特性之一,它對模板參數(shù)進(jìn)行了高度泛化,能表示0到任意個數(shù)、任意類型的參數(shù),這篇文章主要介紹了C++可變參數(shù)模板的展開方式,需要的朋友可以參考下

原樣轉(zhuǎn)發(fā)的意義

前文我們實現(xiàn)了一個my_move函數(shù),用來模擬stl的move操作,實現(xiàn)去引用的功能。其內(nèi)部的原理就是通過remove_reference實現(xiàn)去引用操作。

有時我們也需要保留原類型的左值或者右值屬性,進(jìn)行原樣轉(zhuǎn)發(fā),此時就要用forward實現(xiàn)轉(zhuǎn)發(fā)功能。

我們先定義一個模板函數(shù)

template <typename F, typename T1, typename T2>
void flip1(F f, T1 t1, T2 t2)
{
    f(t2, t1);
}

flip1內(nèi)部調(diào)用了函數(shù)f

我們寫一個函數(shù)測試

void ftemp(int v1, int &v2)
{
    cout << v1 << " " << ++v2 << endl;
}
void use_ftemp(){
    int j = 100;
    int i = 99;
    flip1(ftemp, j, 42);
    cout << "i is " << i << " j is " << j << endl;
}

通過打印發(fā)現(xiàn)i和j的值沒有變化,因為ftemp的v2參數(shù)雖然是引用,但是是flip1的形參t1的引用

t1只是形參,修改t1并不能影響外邊的實參j。

想要達(dá)到修改實參的目的,需要將flip1的參數(shù)修改為引用,我們先實現(xiàn)修改后的版本flip2

template <typename F, typename T1, typename T2>
void flip2(F f, T1 &&t1, T2 &&t2)
{
    f(t2, t1);
}

我們定義了一個flip2函數(shù),t1和t2分別是右值引用類型。接下來用一個測試函數(shù)進(jìn)行測試

int j = 100;
int i = 99;
flip2(ftemp, j, 42);
cout << "i is " << i << " j is " << j << endl;

這次我們發(fā)現(xiàn)j被修改了,因為flip2的t1參數(shù)類型為T1的右值引用,當(dāng)把實參j賦值給flip2時,T1變?yōu)閕nt&,

t1的類型就是int& &&,通過折疊t1變?yōu)閕nt&類型。這樣t1就和實參j綁定了,在flip2內(nèi)部修改t1,就達(dá)到了修改j的目的。

但是flip2同樣存在一個問題,如果flip2的第一個參數(shù)f,如果f是一個接受右值引用參數(shù)的函數(shù),會出現(xiàn)編譯錯誤。

為說明這一點,我們實現(xiàn)一個接納模板參數(shù)右值引用類型的函數(shù)

void gtemp(int &&i, int &j)
{
    cout << "i is " << i << " j is " << j << endl;
}

此時如果我們將gtemp作為參數(shù)傳遞給flip2會報錯

int j = 100;
int i = 99;
// flip2(gtemp, j, 42) 會報錯
// 因為42作為右值純遞給flip2,t2會被折疊為int&類型
// t2傳遞給gtemp第一個參數(shù)時,int&&無法綁定int&類型
//flip2(gtemp, i, 42);
cout << "i is " << i << " j is " << j << endl;

當(dāng)我們將42傳遞給flip2第二個參數(shù)時,T2被實例化為int類型,t2就變?yōu)閕nt && 類型,通過折疊t2變?yōu)閕nt&類型。

t2作為參數(shù)傳遞給gtemp的第一個參數(shù)時會報錯,

cannot bind rvalue reference of type ‘int&&’ to lvalue of type ‘int’

因為t2是一個左值,右值無法綁定該左值。

解決的辦法就是實現(xiàn)一個flip函數(shù),內(nèi)部實現(xiàn)對T2,T1類型的原樣轉(zhuǎn)發(fā)。

template <typename F, typename T1, typename T2>
void flip(F f, T1 &&t1, T2 &&t2)
{
    f(std::forward<T2>(t2), std::forward<T1>(t1));
}

通過forward將t2類型轉(zhuǎn)化為和T2類型一樣的類型,也就是int的右值類型,接下來的調(diào)用就不會出問題了

void use_ftemp()
{
    int j = 100;
    int i = 99;
    flip(gtemp, i, 42);
    cout << "i is " << i << " j is " << j << endl;
}

模板的可變參數(shù)

模板同樣支持可變參數(shù)

//可變參數(shù)的函數(shù)模板
template <typename T>
ostream &print(ostream &os, const T &t)
{
    return os << t; //輸出最后一個元素
}
template <typename T, typename... Args>
ostream &print(ostream &os, const T &t, const Args &...rest)
{
    os << t << ", ";
    return print(os, rest...);
}

Args是可變的模板參數(shù)包, 然后再用Args定義rest變量,這是一個可變參數(shù)列表。

我們的模板函數(shù)print內(nèi)部調(diào)用stl的print函數(shù),通過對rest…實現(xiàn)展開操作。

調(diào)用過程可按如下的方式

void use_printtemp()
{
    int i = 100;
    string s = "hello zack!!!";
    print(cout, i, s, 42);
}

第一次調(diào)用print實際是調(diào)用的可變參數(shù)的print,之后才調(diào)用沒有可變參數(shù)的print函數(shù)。

總結(jié)

本文介紹了模板類型的原樣轉(zhuǎn)發(fā),以及多模板參數(shù)列表的使用。

視頻鏈接

源碼鏈接

到此這篇關(guān)于淺析C++模板類型中的原樣轉(zhuǎn)發(fā)和可變參數(shù)有什么意義的文章就介紹到這了,更多相關(guān)C++原樣轉(zhuǎn)發(fā)和可變參數(shù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語言用函數(shù)實現(xiàn)反彈球消磚塊

    C語言用函數(shù)實現(xiàn)反彈球消磚塊

    這篇文章主要為大家詳細(xì)介紹了C語言用函數(shù)實現(xiàn)反彈球消磚塊,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • C語言中((type *)0) 和(type *0)區(qū)別小結(jié)

    C語言中((type *)0) 和(type *0)區(qū)別小結(jié)

    ((type *)0)?和?(type *0)?在 C 和 C++ 中有不同的含義和用途,本文主要介紹了C語言中((type *)0) 和(type *0)區(qū)別,具有一定的參考價值,感興趣的可以了解一下
    2024-08-08
  • C++中初始化二維數(shù)組的幾種常見方法

    C++中初始化二維數(shù)組的幾種常見方法

    本文詳細(xì)介紹了在C++中初始化二維數(shù)組的不同方式,包括靜態(tài)初始化、循環(huán)、全部為零、部分初始化、std::array和std::vector,以及std::vector作為動態(tài)二維數(shù)組的靈活性和應(yīng)用場景,需要的朋友可以參考下
    2025-04-04
  • C++實戰(zhàn)之二進(jìn)制數(shù)據(jù)處理與封裝

    C++實戰(zhàn)之二進(jìn)制數(shù)據(jù)處理與封裝

    在電腦上一切數(shù)據(jù)都是通過二進(jìn)制(0或1)進(jìn)行存儲的,通過多位二進(jìn)制數(shù)據(jù)可以進(jìn)而表示整形、浮點型、字符、字符串等各種基礎(chǔ)類型數(shù)據(jù)或者一些更復(fù)雜的數(shù)據(jù)格式。本文將為大家詳細(xì)講講二進(jìn)制數(shù)據(jù)處理與封裝,需要的可以參考一下
    2022-08-08
  • C語言實現(xiàn)三子棋游戲的示例代碼

    C語言實現(xiàn)三子棋游戲的示例代碼

    今天我們將會用C語言實現(xiàn)三子棋。所謂三子棋,就是三行三列的棋盤,玩家可以和電腦下棋,率先連成三個的獲勝。話不多說,我們開始吧
    2022-10-10
  • Qt 添加MSVC2017編譯器的完整教程(保姆級)

    Qt 添加MSVC2017編譯器的完整教程(保姆級)

    本文主要介紹了Qt 添加MSVC2017編譯器的完整教程,文中通過圖文介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-06-06
  • C/C++ Qt ToolBar菜單組件的具體使用

    C/C++ Qt ToolBar菜單組件的具體使用

    ToolBar工具欄在所有窗體應(yīng)用程序中都廣泛被使用,使用ToolBar可以很好的規(guī)范菜單功能分類,本文就詳細(xì)的介紹一下ToolBar組件的應(yīng)用,感興趣的可以了解一下
    2021-11-11
  • C++實現(xiàn)商店倉庫管理系統(tǒng)

    C++實現(xiàn)商店倉庫管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C++實現(xiàn)商店倉庫管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • C/C++中獲取重載函數(shù)地址的方法

    C/C++中獲取重載函數(shù)地址的方法

    函數(shù)重載是函數(shù)的一種特殊情況,C++允許在同一作用域中聲明幾個功能類似的同名函數(shù),這 些同名函數(shù)的形參列表不同,常用來處理實現(xiàn)功能類似數(shù)據(jù)類型不同的問題,本文給大家介紹了C/C++中獲取重載函數(shù)地址的方法,需要的朋友可以參考下
    2024-04-04
  • C語言實現(xiàn)宿舍管理課程設(shè)計

    C語言實現(xiàn)宿舍管理課程設(shè)計

    這篇文章主要為大家詳細(xì)介紹了C語言實現(xiàn)宿舍管理課程設(shè)計,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03

最新評論

交城县| 彩票| 观塘区| 雷波县| 东乡县| 麻栗坡县| 左云县| 双辽市| 苏尼特右旗| 曲麻莱县| 昔阳县| 四子王旗| 黑山县| 大洼县| 平顺县| 河东区| 油尖旺区| 新晃| 晋中市| 怀来县| 惠水县| 新宁县| 永康市| 正镶白旗| 英吉沙县| 广南县| 佳木斯市| 涞源县| 新龙县| 苍南县| 维西| 平塘县| 梧州市| 绍兴县| 晴隆县| 青浦区| 永川市| 无锡市| 盐边县| 苗栗市| 铜川市|