91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C++模板類型中的原樣轉發和可變參數怎么實現

發布時間:2022-08-09 17:30:20 來源:億速云 閱讀:128 作者:iii 欄目:開發技術

今天小編給大家分享一下C++模板類型中的原樣轉發和可變參數怎么實現的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。

原樣轉發的意義

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

有時我們也需要保留原類型的左值或者右值屬性,進行原樣轉發,此時就要用forward實現轉發功能。

我們先定義一個模板函數

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

flip1內部調用了函數f

我們寫一個函數測試

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;
}

通過打印發現i和j的值沒有變化,因為ftemp的v2參數雖然是引用,但是是flip1的形參t1的引用

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

想要達到修改實參的目的,需要將flip1的參數修改為引用,我們先實現修改后的版本flip2

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

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

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

這次我們發現j被修改了,因為flip2的t1參數類型為T1的右值引用,當把實參j賦值給flip2時,T1變為int&,

t1的類型就是int& &&,通過折疊t1變為int&類型。這樣t1就和實參j綁定了,在flip2內部修改t1,就達到了修改j的目的。

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

為說明這一點,我們實現一個接納模板參數右值引用類型的函數

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

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

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

當我們將42傳遞給flip2第二個參數時,T2被實例化為int類型,t2就變為int && 類型,通過折疊t2變為int&類型。

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

cannot bind rvalue reference of type &lsquo;int&&&rsquo; to lvalue of type &lsquo;int&rsquo;

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

解決的辦法就是實現一個flip函數,內部實現對T2,T1類型的原樣轉發。

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類型轉化為和T2類型一樣的類型,也就是int的右值類型,接下來的調用就不會出問題了

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

模板的可變參數

模板同樣支持可變參數

//可變參數的函數模板
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是可變的模板參數包, 然后再用Args定義rest變量,這是一個可變參數列表。

我們的模板函數print內部調用stl的print函數,通過對rest&hellip;實現展開操作。

調用過程可按如下的方式

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

第一次調用print實際是調用的可變參數的print,之后才調用沒有可變參數的print函數。

以上就是“C++模板類型中的原樣轉發和可變參數怎么實現”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

c++
AI

射阳县| 邻水| 隆安县| 淳安县| 长汀县| 怀安县| 泗洪县| 特克斯县| 韶山市| 文安县| 济南市| 共和县| 赤壁市| 中卫市| 勃利县| 瑞昌市| 梅州市| 武宣县| 沙洋县| 施秉县| 麻栗坡县| 广宗县| 吴忠市| 加查县| 广汉市| 河南省| 拜泉县| 特克斯县| 会理县| 志丹县| 醴陵市| 余江县| 类乌齐县| 神农架林区| 霍州市| 蓝田县| 怀宁县| 寻甸| 公安县| 西青区| 乌海市|