C++可變參數(shù)的函數(shù)與模板實例分析
本文實例展示了C++可變參數(shù)的函數(shù)與模板的實現(xiàn)方法,有助于大家更好的理解可變參數(shù)的函數(shù)與模板的應(yīng)用,具體內(nèi)容如下:
首先,所謂可變參數(shù)指的是函數(shù)的參數(shù)個數(shù)可變,參數(shù)類型不定的函數(shù)。為了編寫能處理不同數(shù)量實參的函數(shù),C++提供了兩種主要的方法:如果所有的實參類型相同,可以傳遞一個名為initializer_list的標(biāo)準(zhǔn)庫類型;如果實參的類型不同,我們可以編寫可變參數(shù)模板。另外,C++還有一種特殊的省略符形參,可以用它傳遞可變數(shù)量的實參,不過這種一般只用于與C函數(shù)交互的接口程序。
一、可變參數(shù)函數(shù)
1、initializer_list形參
如果函數(shù)的實參數(shù)量未知但是全部實參的類型都相同,我們可以使用initializer_list類型的形參(C++11新標(biāo)準(zhǔn))。和vector一樣,initializer_list也是一種模板類型。下面看看initializer_list提供的一些操作:
#include<initializer_list> // 頭文件 initializer_list<T> lst; // 默認(rèn)初始化,T類型元素的空列表 initializer_list<T> lst{a,b,c...}; // 初始化為初始值列表的副本 lst2(lst) // 拷貝或賦值不會拷貝列表中的元素;拷貝后, lst2 = lst // 原始列表和副本共享元素 lst.size() // 列表中的元素數(shù)量 lst.begin() // 返回指向lst中首元素的指針 lst.end() // 返回指向lst中尾元素下一位置的指針
下面給出一個例子,需要注意的是,含有initializer_list形參的函數(shù)也可以同時擁有其他形參。另外,如果想給initializer_list形參傳遞一個實參的序列,必須把序列放在一對花括號內(nèi):
string func(initializer_list<string> li) { string str(""); for(auto beg=li.begin(); beg!=li.end(); ++beg) str += *beg; return str; } int main() { cout << func({"This"," ","is"," ","C++"}) << endl; return 0; }
2、省略符形參
函數(shù)可以用省略符形參”…“表示不定參數(shù)部分,省略符形參只能出現(xiàn)在形參列表的最后一個位置,它的形式如下:
void foo(parm_list, ...); // 典型例子 int printf(const char* format, ...)
省略符形參應(yīng)該僅僅用于C和C++通用的類型,因為大多數(shù)類類型的對象在傳遞給省略符形參時都無法正確拷貝。下面是<cstdarg>頭文件中的幾個宏定義:
#include<cstdarg> // C中是<stdarg.h> // va_list是一種數(shù)據(jù)類型,args用于持有可變參數(shù)。 // 定義typedef char* va_list; va_list args; // 調(diào)用va_start并傳入兩個參數(shù):第一個參數(shù)為va_list類型的變量 // 第二個參數(shù)為"..."前最后一個參數(shù)名 // 將args初始化為指向第一個參數(shù)(可變參數(shù)列表) va_start(args, paramN); // 檢索參數(shù),va_arg的第一個參數(shù)是va_list變量,第二個參數(shù)指定返回值的類型 // 每一次調(diào)用va_arg會獲取當(dāng)前的參數(shù),并自動更新指向下一個可變參數(shù)。 va_arg(args,type); // 釋放va_list變量 va_end(args);
下面給出一個例子:
int add_nums(int count,...) { int result = 0; va_list args; va_start(args, count); for(int i=0; i<count; ++i) result += va_arg(args, int); va_end(args); return result; } int main() { cout << add_nums(4, 25, 25, 50, 50) << endl; return 0; }
編譯器是將參數(shù)壓入棧中進(jìn)行傳遞的。傳遞實參的時候,編譯器會從實參列表中,按從右到左的順序?qū)?shù)入棧,對于add_nums(4, 25, 25, 50, 50)的調(diào)用,則入棧的順序是 50, 50, 25, 25, 4 (注意沒有可變參數(shù)與不可變參數(shù)之分)。由于棧的地址是從高到低的,所以在知道了第一個參數(shù)地址和參數(shù)的類型之后,就可以獲取各個參數(shù)的地址。
二、可變參數(shù)模板
一個可變參數(shù)模板(variadic template)就是一個接受可變數(shù)目參數(shù)的模板函數(shù)或模板類??勺償?shù)目的參數(shù)被稱為參數(shù)包(parameter packet)。存在兩種參數(shù)包:模板參數(shù)包(表示零個或多個模板參數(shù))和函數(shù)參數(shù)包(表示零個或多個函數(shù)參數(shù))。
上述說到我們可以使用一個initializer_list來定義一個可接受可變數(shù)目實參的函數(shù),但是所有實參必須具有相同的類型。當(dāng)我們既不知道要處理的實參數(shù)目也不知道它們的類型時,我們就需要使用可變參數(shù)的函數(shù)模板了。我們用一個省略號來指出一個模板參數(shù)或函數(shù)參數(shù)表示一個包:在一個模板參數(shù)列表中,class...或typename...指出接下來的參數(shù)表示零個或多個類型的列表;一個類型名后面跟一個省略號表示零個或多個給定類型的非類型參數(shù)的列表。在函數(shù)參數(shù)列表中,如果一個參數(shù)的類型是一個模板參數(shù)包,則此參數(shù)也是一個函數(shù)參數(shù)包。
// Args是一個模板參數(shù)包;rest是一個函數(shù)參數(shù)包 template <typename T, typename...Args> void foo(const T &t, const Args&...rest);
可變參數(shù)函數(shù)模板通常是遞歸的。第一步調(diào)用處理包中的第一個實參,然后用剩余的實參調(diào)用自身。為了終止遞歸,我們還需要定義一個非可變參數(shù)的函數(shù)模板:
// 用來終止遞歸并處理包中最后一個元素 template <typename T> void print(const T &t) { cout << t; } // 包中除了最后一個元素之外的其他元素都會調(diào)用這個版本的print template <typename T, typename...Args> void print(const T &t, const Args&...rest) { cout << t << " "; // 打印第一個實參 print(rest...); // 遞歸調(diào)用,打印其他實參 } // 測試 int main() { print("string1", 2, 3.14f, "string2", 42); cout << endl; return 0; }
非可變參數(shù)版本的print負(fù)責(zé)終止遞歸并打印初始調(diào)用中的最后一個實參。對于最后一次遞歸調(diào)用print(42),兩個print版本都是可行的。但是,非可變參數(shù)模板比可變參數(shù)模板更特例化,因此編譯器選擇非可變參數(shù)版本。
上一篇:C++變位詞問題分析
欄 目:C語言
下一篇:C++實現(xiàn)第K順序統(tǒng)計量的求解方法
本文標(biāo)題:C++可變參數(shù)的函數(shù)與模板實例分析
本文地址:http://mengdiqiu.com.cn/a1/Cyuyan/3499.html
您可能感興趣的文章
- 04-02c語言沒有round函數(shù) round c語言
- 01-10深入理解C++中常見的關(guān)鍵字含義
- 01-10使用C++實現(xiàn)全排列算法的方法詳解
- 01-10深入Main函數(shù)中的參數(shù)argc,argv的使用詳解
- 01-10c++中inline的用法分析
- 01-10用C++實現(xiàn)DBSCAN聚類算法
- 01-10全排列算法的非遞歸實現(xiàn)與遞歸實現(xiàn)的方法(C++)
- 01-10C++大數(shù)模板(推薦)
- 01-10淺談C/C++中的static與extern關(guān)鍵字的使用詳解
- 01-10深入C/C++浮點數(shù)在內(nèi)存中的存儲方式詳解


閱讀排行
本欄相關(guān)
- 04-02c語言函數(shù)調(diào)用后清空內(nèi)存 c語言調(diào)用
- 04-02func函數(shù)+在C語言 func函數(shù)在c語言中
- 04-02c語言的正則匹配函數(shù) c語言正則表達(dá)
- 04-02c語言用函數(shù)寫分段 用c語言表示分段
- 04-02c語言中對數(shù)函數(shù)的表達(dá)式 c語言中對
- 04-02c語言編寫函數(shù)冒泡排序 c語言冒泡排
- 04-02c語言沒有round函數(shù) round c語言
- 04-02c語言分段函數(shù)怎么求 用c語言求分段
- 04-02C語言中怎么打出三角函數(shù) c語言中怎
- 04-02c語言調(diào)用函數(shù)求fibo C語言調(diào)用函數(shù)求
隨機(jī)閱讀
- 08-05dedecms(織夢)副欄目數(shù)量限制代碼修改
- 08-05DEDE織夢data目錄下的sessions文件夾有什
- 08-05織夢dedecms什么時候用欄目交叉功能?
- 01-10delphi制作wav文件的方法
- 01-10C#中split用法實例總結(jié)
- 01-11ajax實現(xiàn)頁面的局部加載
- 01-10使用C語言求解撲克牌的順子及n個骰子
- 04-02jquery與jsp,用jquery
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文