亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C++ > 正文

C++可變參數的函數與模板實例分析

2020-01-26 15:23:54
字體:
來源:轉載
供稿:網友

本文實例展示了C++可變參數的函數與模板的實現方法,有助于大家更好的理解可變參數的函數與模板的應用,具體內容如下:

首先,所謂可變參數指的是函數的參數個數可變,參數類型不定的函數。為了編寫能處理不同數量實參的函數,C++提供了兩種主要的方法:如果所有的實參類型相同,可以傳遞一個名為initializer_list的標準庫類型;如果實參的類型不同,我們可以編寫可變參數模板。另外,C++還有一種特殊的省略符形參,可以用它傳遞可變數量的實參,不過這種一般只用于與C函數交互的接口程序。

一、可變參數函數

1、initializer_list形參

如果函數的實參數量未知但是全部實參的類型都相同,我們可以使用initializer_list類型的形參(C++11新標準)。和vector一樣,initializer_list也是一種模板類型。下面看看initializer_list提供的一些操作:

#include<initializer_list> // 頭文件 initializer_list<T> lst;  // 默認初始化,T類型元素的空列表 initializer_list<T> lst{a,b,c...}; // 初始化為初始值列表的副本 lst2(lst)   // 拷貝或賦值不會拷貝列表中的元素;拷貝后, lst2 = lst  // 原始列表和副本共享元素 lst.size()  // 列表中的元素數量 lst.begin()  // 返回指向lst中首元素的指針 lst.end()   // 返回指向lst中尾元素下一位置的指針

下面給出一個例子,需要注意的是,含有initializer_list形參的函數也可以同時擁有其他形參。另外,如果想給initializer_list形參傳遞一個實參的序列,必須把序列放在一對花括號內:

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、省略符形參

函數可以用省略符形參”…“表示不定參數部分,省略符形參只能出現在形參列表的最后一個位置,它的形式如下:

void foo(parm_list, ...); // 典型例子 int printf(const char* format, ...) 

省略符形參應該僅僅用于C和C++通用的類型,因為大多數類類型的對象在傳遞給省略符形參時都無法正確拷貝。下面是<cstdarg>頭文件中的幾個宏定義:

#include<cstdarg> // C中是<stdarg.h>  // va_list是一種數據類型,args用于持有可變參數。 // 定義typedef char* va_list; va_list args;  // 調用va_start并傳入兩個參數:第一個參數為va_list類型的變量 // 第二個參數為"..."前最后一個參數名 // 將args初始化為指向第一個參數(可變參數列表) va_start(args, paramN);  // 檢索參數,va_arg的第一個參數是va_list變量,第二個參數指定返回值的類型 // 每一次調用va_arg會獲取當前的參數,并自動更新指向下一個可變參數。 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; } 

編譯器是將參數壓入棧中進行傳遞的。傳遞實參的時候,編譯器會從實參列表中,按從右到左的順序將參數入棧,對于add_nums(4, 25, 25, 50, 50)的調用,則入棧的順序是 50, 50, 25, 25, 4 (注意沒有可變參數與不可變參數之分)。由于棧的地址是從高到低的,所以在知道了第一個參數地址和參數的類型之后,就可以獲取各個參數的地址。

二、可變參數模板

一個可變參數模板(variadic template)就是一個接受可變數目參數的模板函數或模板類??勺償的康膮当环Q為參數包(parameter packet)。存在兩種參數包:模板參數包(表示零個或多個模板參數)和函數參數包(表示零個或多個函數參數)。

上述說到我們可以使用一個initializer_list來定義一個可接受可變數目實參的函數,但是所有實參必須具有相同的類型。當我們既不知道要處理的實參數目也不知道它們的類型時,我們就需要使用可變參數的函數模板了。我們用一個省略號來指出一個模板參數或函數參數表示一個包:在一個模板參數列表中,class...或typename...指出接下來的參數表示零個或多個類型的列表;一個類型名后面跟一個省略號表示零個或多個給定類型的非類型參數的列表。在函數參數列表中,如果一個參數的類型是一個模板參數包,則此參數也是一個函數參數包。

// Args是一個模板參數包;rest是一個函數參數包 template <typename T, typename...Args> void foo(const T &t, const Args&...rest); 

可變參數函數模板通常是遞歸的。第一步調用處理包中的第一個實參,然后用剩余的實參調用自身。為了終止遞歸,我們還需要定義一個非可變參數的函數模板:

// 用來終止遞歸并處理包中最后一個元素 template <typename T> void print(const T &t) {   cout << t; }  // 包中除了最后一個元素之外的其他元素都會調用這個版本的print template <typename T, typename...Args> void print(const T &t, const Args&...rest) {   cout << t << " ";   // 打印第一個實參   print(rest...);    // 遞歸調用,打印其他實參 }  // 測試 int main() {   print("string1", 2, 3.14f, "string2", 42);   cout << endl;   return 0; } 

非可變參數版本的print負責終止遞歸并打印初始調用中的最后一個實參。對于最后一次遞歸調用print(42),兩個print版本都是可行的。但是,非可變參數模板比可變參數模板更特例化,因此編譯器選擇非可變參數版本。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲国产精品电影| 日韩欧美精品网址| 日韩有码在线电影| 亚洲综合中文字幕在线观看| 国产情人节一区| 宅男66日本亚洲欧美视频| 中文在线资源观看视频网站免费不卡| 日韩欧美精品网址| 97国产在线视频| 欧美午夜精品在线| 777国产偷窥盗摄精品视频| 欧美激情影音先锋| 亚洲精品免费网站| 日韩亚洲欧美中文在线| 国产一区二中文字幕在线看| 欧美专区在线播放| 日韩黄色高清视频| 欧美专区国产专区| 日韩成人av在线| 九九久久国产精品| 久久精品中文字幕一区| 中文字幕亚洲专区| 91性高湖久久久久久久久_久久99| 国产一区二区三区高清在线观看| 97免费中文视频在线观看| 欧美日韩福利在线观看| 久久综合久中文字幕青草| 欧美性生交xxxxxdddd| 91精品国产高清久久久久久久久| 91在线观看免费观看| 欧美成人免费视频| 亚洲男人天堂九九视频| 日韩高清免费在线| 久久亚洲精品小早川怜子66| 超在线视频97| 国产精品一区二区久久| 午夜免费日韩视频| 国产九九精品视频| 亚洲精品中文字幕女同| 亚洲黄页网在线观看| 九九热这里只有精品6| 久久露脸国产精品| 国产精品久久久久久亚洲调教| 日韩电影中文字幕在线| 日韩中文字幕国产精品| 国产aaa精品| 久久噜噜噜精品国产亚洲综合| 国产精品丝袜白浆摸在线| 欧美黑人视频一区| 欧美激情xxxx性bbbb| 色爱精品视频一区| 日韩大片免费观看视频播放| 另类天堂视频在线观看| 亚洲欧美中文字幕在线一区| 色综合视频网站| 国产精品自产拍在线观看| 久久精品国产精品亚洲| 亚洲精品免费在线视频| 欧美亚洲一区在线| 国产91色在线|| 国产福利视频一区二区| 亚洲乱码国产乱码精品精| 色偷偷9999www| 欧美成人h版在线观看| 色偷偷噜噜噜亚洲男人的天堂| 国产精品美女久久| 欧美午夜美女看片| 性色av一区二区三区| 国产精品v片在线观看不卡| 中文字幕精品www乱入免费视频| 午夜精品久久久久久99热| 亚洲精品欧美极品| 色综合久久久久久中文网| 日韩免费在线电影| 国产精品日韩在线一区| 国产精品ⅴa在线观看h| 久久久精品一区二区三区| 性欧美办公室18xxxxhd| 亚洲一区二区三区久久| 精品国产精品三级精品av网址| 亚洲区一区二区| 精品调教chinesegay| 亚洲精品动漫久久久久| 亚洲国产精久久久久久久| 日韩电影中文字幕一区| 亚洲国产精品福利| 国产91九色视频| 久久香蕉精品香蕉| 亚洲精品网站在线播放gif| 欧美精品激情在线| 精品久久久国产| 日韩中文字幕不卡视频| 亚洲理论电影网| 午夜免费日韩视频| 一本一本久久a久久精品综合小说| 亚州精品天堂中文字幕| 国产精品入口尤物| 亚洲欧洲一区二区三区在线观看| 亚洲欧美日本另类| 亚洲精品黄网在线观看| 欧美国产日韩xxxxx| 国产精品扒开腿做爽爽爽的视频| 久久久人成影片一区二区三区观看| 亚洲福利精品在线| 久久久久国色av免费观看性色| 国产欧美 在线欧美| 日韩精品一二三四区| 久久噜噜噜精品国产亚洲综合| 日本韩国在线不卡| 伊人伊人伊人久久| 中文字幕欧美在线| 色婷婷av一区二区三区久久| 久久天天躁狠狠躁夜夜躁2014| 欧美一区二区三区图| 狠狠躁天天躁日日躁欧美| 日韩女优人人人人射在线视频| 久久久久久久成人| 91免费版网站入口| 精品亚洲一区二区三区| 欧美又大又硬又粗bbbbb| 亚洲欧美日韩第一区| 国产99在线|中文| 97久久久免费福利网址| 日韩电影免费观看在线| 欧美一二三视频| 亚洲电影免费观看高清完整版在线| 亚洲尤物视频网| 69av在线播放| 欧美在线视频a| 国产拍精品一二三| 中文字幕精品一区久久久久| 成人欧美一区二区三区在线| 久久好看免费视频| 欧美高清电影在线看| 亚洲精品成a人在线观看| 另类专区欧美制服同性| 91视频免费在线| 久久99精品久久久久久琪琪| 久久免费国产精品1| 精品亚洲精品福利线在观看| 日本欧美国产在线| 亚洲精品视频免费| 日韩免费观看视频| 日韩亚洲欧美中文在线| 亚洲另类xxxx| 欧美一级高清免费播放| 亚洲情综合五月天| 色综合视频一区中文字幕| 国产免费一区二区三区在线能观看| 欧美午夜xxx| 日韩中文字幕精品视频| 中文字幕亚洲一区二区三区| 久久精品电影一区二区| 亚洲国模精品一区| 这里只有精品久久| 欧美视频在线免费看| 操91在线视频| 成人乱人伦精品视频在线观看| 欧美在线性视频| 亚洲国产精品久久久久秋霞蜜臀| 欧美日韩中文字幕| 91精品国产成人| 红桃av永久久久| 久久免费精品日本久久中文字幕|