c 中如何使用可變引數的函式(學習筆記)

2021-10-05 22:27:07 字數 2203 閱讀 6867

在c++中我們需要同種函式擁有不同種的功能時,首先想到的函式過載,但是過載種模擬較多時我們會使用模板函式(或者是模板函式過載以及模板函式的具體化)來幫助我們更加泛化,但這些方法的特點是函式引數的個數是確定的,假如我們需要引數個數是可以動態變化的話,上面的幾個方法就不夠用了。這時我們就可以使用variadic template以及initializer_list來解決這個問題。

用print函式來演示上述兩種方法

void

print()

template ,typename ... types>

void

print

(t first ,types ... rest)

簡單分析一下,上面使用了這個…這個非常關鍵的東西pack,這個包的概念是比較重要的。可以這樣理解,…在模板引數列表中放在typename的後面,代表有…個typename,然後把這…稱為template parameter packs(模板引數包),並起名為types。

函式中的…被稱為function parameter types pack(函式引數型別包),這個pack可以給個名字rest。

進入函式列印完first之後進入遞迴,這時我們傳的引數是剛才的pack,這個pack再分解為乙個型別加乙個包,依此類推,直到後面分解為乙個型別加0個包,這也就是我們為什麼要定義乙個無引數的空的print函式。

假如需要了解到我們傳進去的引數個數有多少個,我們可以用sizeof運算子

sizeof...

(rest)+1

;

注意這個…的位置,放錯位置會報莫名其妙的錯誤。測試程式可以是

int main()

然後他就能列印出所有的引數了。

第二種是initializer_list,這時乙個類模板,所以我們使用的時候需要為它指定型別,當然,這個型別也可以是模板。例項如下。

//initialize_list 迭代版本的print

#include

#include

template>

void

print

(initializer_list<

t> inilist)

}

這個用法本身比較簡單,不過從**我們也可以看出它可以任意個數,但不能任意型別,必須是同種型別。而且型別必須嚴格一致或者是可以進行型別轉換的(所以你得清楚什麼樣的型別轉換是允許或者說是安全的),函式的書寫方式也有細節需要注意,放**吧

//注意呼叫方式,須將引數用大括號括起來

int main()

);//執行通過

print()

;//執行也通過,因為可以呼叫string 的建構函式把字串轉化為string型別

print()

//error,型別不匹配

print()

;//通過

print()

;//通過

print()

;//通過

//另外一種初始化方式

initializer_list mystring =

;//時刻注意這是乙個類,所以也是可以建立物件的,這樣就可以用我們習慣的方式呼叫print函式了。

print

(mystring)

;//通過

cin.

get();

}

**雖然看起來多,但是關鍵就是知道怎麼樣得型別才是允許的,安全的。

然後我們可以用這個方式做一些更好的事情,比如比較大小。

常用的比較大小是兩個兩個比較的,但是用這個就可以一次性比較多個。stl庫裡面的min函式的引數就是這個類。我們可以試著簡單實現一下。

template>

tminfun

(initializer_list<

t> inilist)

return

*found;

}int main()

; int a =

minfun

(ini)

; cout << a << endl;

cin.

get();

}

執行過後是符合我們的基本功能的。

C中可變引數函式

先說明規則 1.函式的可變引數中必須有一條確定的引數 至少一條 2.可變引數列表必須從頭開始訪問,訪問到尾部 3.可變引數列變不能確定引數數目 編譯時才能確定 4.可變引數的變數型別是不確定的,編譯時必須確定引數型別,變數的引數型別不確定時,函式的結果未知。引數使用方法 include va lis...

函式中的可變引數c

在資料的大小,個數,型別是未知的情況下,會用到可變引數。include include include 標準引數,解決可變引數問題 intadd int num,va end argp 結束讀取 return res void main include include include 標準引數,解決...

C 中函式中的可變引數

using system using system.collections.generic using system.linq using system.text vfun values console.writeline vfun aaa bbb ccc console.writeline say...