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

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

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

2020-05-23 14:22:09
字體:
來源:轉載
供稿:網友

本文實例展示了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
欧美日韩国产色视频| 欧美成人激情图片网| 亚洲女人被黑人巨大进入al| 国产性色av一区二区| 精品国产福利在线| 在线电影欧美日韩一区二区私密| 亚洲成人黄色在线| 精品欧美一区二区三区| 日韩在线免费观看视频| 成人国产精品久久久久久亚洲| 欧美大尺度电影在线观看| 日韩av电影手机在线| 亚洲午夜久久久久久久| 亚洲理论片在线观看| 日韩欧美视频一区二区三区| 国产精品高清免费在线观看| 国产精品自产拍在线观看中文| 97av在线影院| 欧美黑人性视频| 色妞在线综合亚洲欧美| 亚洲综合日韩在线| 久久这里只有精品视频首页| 色综合久久中文字幕综合网小说| www.日韩.com| 成人有码视频在线播放| 国产精品视频男人的天堂| 国产精品香蕉在线观看| 国产精品入口尤物| 26uuu久久噜噜噜噜| 亚洲午夜久久久久久久| 在线中文字幕日韩| 欧美极品少妇全裸体| 欧美在线视频一二三| 亚洲黄色成人网| 日韩精品中文字幕久久臀| 97精品久久久中文字幕免费| 久久久亚洲精选| 国产精品视频久久| 精品亚洲一区二区三区在线播放| 欧美夫妻性生活xx| 91久久国产综合久久91精品网站| 亚洲最新在线视频| 国内精品一区二区三区四区| 亚洲欧美999| 欧美亚洲国产成人精品| 中文字幕av一区中文字幕天堂| 亚洲第一区第一页| 在线一区二区日韩| 日韩经典中文字幕在线观看| 8x海外华人永久免费日韩内陆视频| 欧美影院久久久| 91国产高清在线| 久久视频在线免费观看| 精品国产一区二区三区久久狼黑人| 日韩欧美极品在线观看| 欧美日在线观看| 亚洲欧美一区二区三区情侣bbw| 欧美久久久精品| 国产亚洲一区二区在线| 最近2019年中文视频免费在线观看| 久久精品视频在线观看| 亚洲美女福利视频网站| 亚洲精品在线看| 亚洲激情视频在线| 国产一区二区精品丝袜| 欧美日韩国产一区中文午夜| 久久九九精品99国产精品| 日本免费在线精品| 欧美午夜丰满在线18影院| 国产精品成人观看视频国产奇米| 欧美国产第一页| 日韩中文字幕在线| 精品久久久久久久久久久久久久| 在线观看视频99| 尤物九九久久国产精品的特点| 久久综合网hezyo| 国产成人av网| 最近2019免费中文字幕视频三| 91久久在线观看| 97久久精品人人澡人人爽缅北| 亚洲欧美一区二区三区在线| 国产一区二区黑人欧美xxxx| 最近2019年中文视频免费在线观看| 日本乱人伦a精品| 国产精品欧美一区二区三区奶水| 亚洲a级在线播放观看| 欧美性xxxx极品hd欧美风情| 6080yy精品一区二区三区| 日韩激情第一页| 国产精品久久久久久久久久久新郎| 日韩亚洲一区二区| 亚洲欧美国产日韩中文字幕| 国产精品第1页| 日韩精品免费在线观看| 亚洲精品suv精品一区二区| 久久久精品国产| 久久久99久久精品女同性| 亚洲天堂网在线观看| 欧洲永久精品大片ww免费漫画| 日韩美女av在线| 欧美视频13p| 欧美另类极品videosbest最新版本| 午夜欧美不卡精品aaaaa| 国产精品欧美日韩久久| 日本久久久久久久久久久| 日日狠狠久久偷偷四色综合免费| 高清在线视频日韩欧美| 亚洲人成网7777777国产| 欧美第一黄网免费网站| 日韩视频在线观看免费| 日本不卡视频在线播放| www.日韩系列| 久久精品国产96久久久香蕉| 久久色免费在线视频| 日韩av免费在线播放| 亚洲第一偷拍网| 欧美有码在线观看| 日韩精品丝袜在线| 国产成人精品久久二区二区91| 日韩av不卡电影| 一区二区三区四区在线观看视频| 韩日精品中文字幕| 美女扒开尿口让男人操亚洲视频网站| 欧美成人免费va影院高清| 欧美国产日本高清在线| 91精品国产自产在线观看永久| 91在线观看免费网站| 亚洲级视频在线观看免费1级| 草民午夜欧美限制a级福利片| 超碰精品一区二区三区乱码| 久久资源免费视频| 色午夜这里只有精品| 亚洲三级黄色在线观看| 久久久久久久久国产精品| 欧美人与性动交a欧美精品| 久久精品国产一区| 久久久久久久久久久91| 日韩av影视在线| 欧美成年人网站| 欧美成人精品h版在线观看| 国产亚洲xxx| 亚洲国产成人精品电影| 国产999精品| 少妇高潮 亚洲精品| 92福利视频午夜1000合集在线观看| 国产网站欧美日韩免费精品在线观看| 久久免费精品日本久久中文字幕| 国产美女精品免费电影| 欧美中文字幕在线播放| 久久97精品久久久久久久不卡| 国产成人久久精品| 久久久精品视频成人| 综合国产在线视频| 在线性视频日韩欧美| 国产精品青草久久久久福利99| 日本伊人精品一区二区三区介绍| 精品无人国产偷自产在线| 国产精品毛片a∨一区二区三区|国| 精品久久久久久电影| 久久久久久久久久久91| 久久精品99久久久香蕉| 亚洲国产黄色片| 国产suv精品一区二区| 55夜色66夜色国产精品视频|