可變形參函式

2021-10-06 19:40:35 字數 2344 閱讀 8661

在c++程式設計中,有時我們需要編寫一些在源**編寫階段無法確定引數個數,有時甚至無法確定引數型別的函式。

因此我們需要一類函式:它們可以在執行時取任意的實參個數並根據實參的個數自動處理不同實參的情形,或者至少可以在執行時指定任意的實參個數。

在c++中實現乙個變參函式的方法有三種:

重點介紹第一種方法和第三種方法

實現步驟如下:

函式原型中使用例項化initializer_list模板代表可變引數列表;

使用迭代器訪問initializer_list中的引數;

傳入實參寫在{}之內。

以上步驟中使用到initializer_list。這是c++11新標準中引入的乙個標準庫型別,與vector等容器一樣,initializer_list也支援begin()和end()操作,返回指向首元素的迭代器和尾後迭代器。initializer_list在同名頭檔案中宣告,其實現由編譯器支援。

以下**使用initializer_list實現函式sum。(忽略可能存在的整形溢位)

/* --sum.cpp-- 利用initializer_list模板實現求人乙個整形值得和 */

#include

intsum

(initializer_list<

int> il)

;//函式原型用int例項化initializer_list作為形參

intsum

(inttializer_list<

int> il)

使用這種方法需要注意一下幾點:

initializer_list在c++11中才被引入,這意味著在編譯時可能需要加上這個選項 -std=c++11 才能成功編譯。上述**中的auto關鍵字也是c++11的一部分;

引數必須放在一組『{}』(大括號)內,編譯器通過大括號來將這組引數轉化為initializer_list.大括號的的一組實參與initializer_list形參對應;

函式原型initializer_list與普通形參無異。這表明形參列表中可以包含其他型別引數且位置不限,以下函式原型是正確的:

void

func

(char c, initializer_list<

int> il,

double d)

;

同乙個initializer_list中的引數具有相同的型別。本質上來說initializer_list是乙個編譯器支援的容器類模板,同其他容器一樣,容器中的元素具有相同的型別。

使用這種方法的乙個例項是c++11中vector的列表初始化建構函式。

在介紹這種方法之前需要先介紹兩個並不常用的概念:模板引數包和函式引數包。

//args是乙個模板引數包;rest是乙個函式引數包

//args表示零個或多個模板型別引數

//rest表示零個或多個函式引數

template

<

typename t,

typename..

. args>

void

foo(

const t &t,

const args&..

. rest)

;

編寫含有模板引數包和函式引數包的模板函式;

函式定義遞迴呼叫自己,每一步遞迴引數包中引數減一;

編寫處理邊界情況(引數包含有零個引數)的模板。

//用來終止遞迴並答應最後乙個元素的函式

//此函式必須在可變引數版本的print定義之前宣告

template

<

typename t>

std::ostream &

print

(std::ostream &os,

const t &t)

//包中除最後乙個元素之外的其他元素都會呼叫這個版本的pirnt

template

<

typename t,

typename..

. args>

std::ostream &

print

(std::ostream &os,

const t &t, cosnt args &..

. rest)

使用這種方法需要注意的是:

1. 必須處理邊界情況。且如**注釋所示:應當首先定義處理邊界情況的模板。

2. 引數包在引數列表最右側,引數包只能從左至右展開?

3. 引數包能夠實現更加複雜的模板

這種實現方式的根本原理實際上與函式過載是一致的。通過定義模板,讓編譯器根據實參型別自動生成對應的過載函式。

含有可變形參的函式

有時候我們想給函式傳遞實參,但是實參的數目又無法預知,這時候該怎麼辦?initializer list形參 如果函式的實參數目未知但是全部實參的型別都相同,可以使用initializer list型別的形參。initializer list是一種標準庫型別,用於表示某種特定型別的值的陣列。initi...

含有可變形參的函式(十四)

例項目的 用可變引數實現個數不定的字串的傳遞 include head.h void print int num,num為可變引數的個數 int main int argc,char argv void print int num,va list argp 需先定義引數列表變數 va start a...

可變參函式

int add int x,int main int add int x,int sum 0 char point char x for int i 0 iint add int x,可變參函式原型,該函式中帶有識別符號的引數 x記錄的是引數的個數,後面的數字是需要求和的數。x的作用是為了標誌出加數...