欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++可變參數(shù)的函數(shù)與模板實(shí)例分析

 更新時(shí)間:2014年08月15日 08:53:40   投稿:shichen2014  
這篇文章主要介紹了C++可變參數(shù)的函數(shù)與模板,非常重要的概念,需要的朋友可以參考下

本文實(shí)例展示了C++可變參數(shù)的函數(shù)與模板的實(shí)現(xiàn)方法,有助于大家更好的理解可變參數(shù)的函數(shù)與模板的應(yīng)用,具體內(nèi)容如下:

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

一、可變參數(shù)函數(shù)

1、initializer_list形參

如果函數(shù)的實(shí)參數(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)   // 拷貝或賦值不會(huì)拷貝列表中的元素;拷貝后, 
lst2 = lst  // 原始列表和副本共享元素 
lst.size()  // 列表中的元素?cái)?shù)量 
lst.begin()  // 返回指向lst中首元素的指針 
lst.end()   // 返回指向lst中尾元素下一位置的指針

下面給出一個(gè)例子,需要注意的是,含有initializer_list形參的函數(shù)也可以同時(shí)擁有其他形參。另外,如果想給initializer_list形參傳遞一個(gè)實(shí)參的序列,必須把序列放在一對(duì)花括號(hào)內(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)在形參列表的最后一個(gè)位置,它的形式如下:

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

省略符形參應(yīng)該僅僅用于C和C++通用的類型,因?yàn)榇蠖鄶?shù)類類型的對(duì)象在傳遞給省略符形參時(shí)都無法正確拷貝。下面是<cstdarg>頭文件中的幾個(gè)宏定義:

#include<cstdarg> // C中是<stdarg.h> 
 
// va_list是一種數(shù)據(jù)類型,args用于持有可變參數(shù)。 
// 定義typedef char* va_list; 
va_list args; 
 
// 調(diào)用va_start并傳入兩個(gè)參數(shù):第一個(gè)參數(shù)為va_list類型的變量 
// 第二個(gè)參數(shù)為"..."前最后一個(gè)參數(shù)名 
// 將args初始化為指向第一個(gè)參數(shù)(可變參數(shù)列表) 
va_start(args, paramN); 
 
// 檢索參數(shù),va_arg的第一個(gè)參數(shù)是va_list變量,第二個(gè)參數(shù)指定返回值的類型 
// 每一次調(diào)用va_arg會(huì)獲取當(dāng)前的參數(shù),并自動(dòng)更新指向下一個(gè)可變參數(shù)。 
va_arg(args,type); 
 
// 釋放va_list變量 
va_end(args);

下面給出一個(gè)例子:

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)行傳遞的。傳遞實(shí)參的時(shí)候,編譯器會(huì)從實(shí)參列表中,按從右到左的順序?qū)?shù)入棧,對(duì)于add_nums(4, 25, 25, 50, 50)的調(diào)用,則入棧的順序是 50, 50, 25, 25, 4 (注意沒有可變參數(shù)與不可變參數(shù)之分)。由于棧的地址是從高到低的,所以在知道了第一個(gè)參數(shù)地址和參數(shù)的類型之后,就可以獲取各個(gè)參數(shù)的地址。

二、可變參數(shù)模板

一個(gè)可變參數(shù)模板(variadic template)就是一個(gè)接受可變數(shù)目參數(shù)的模板函數(shù)或模板類??勺償?shù)目的參數(shù)被稱為參數(shù)包(parameter packet)。存在兩種參數(shù)包:模板參數(shù)包(表示零個(gè)或多個(gè)模板參數(shù))和函數(shù)參數(shù)包(表示零個(gè)或多個(gè)函數(shù)參數(shù))。

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

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

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

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

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

相關(guān)文章

  • C++判斷一個(gè)點(diǎn)是否在圓內(nèi)的方法

    C++判斷一個(gè)點(diǎn)是否在圓內(nèi)的方法

    這篇文章主要為大家詳細(xì)介紹了C++判斷一個(gè)點(diǎn)是否在圓內(nèi)的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-05-05
  • 利用OpenCV實(shí)現(xiàn)局部動(dòng)態(tài)閾值分割

    利用OpenCV實(shí)現(xiàn)局部動(dòng)態(tài)閾值分割

    這篇文章主要為大家詳細(xì)介紹了利用OpenCV實(shí)現(xiàn)局部動(dòng)態(tài)閾值分割,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • 使用C語言操作文件的基本函數(shù)整理

    使用C語言操作文件的基本函數(shù)整理

    這篇文章主要介紹了使用C語言操作文件的基本函數(shù)整理,包括創(chuàng)建和打開以及關(guān)閉文件的操作方法,需要的朋友可以參考下
    2015-08-08
  • c++中nlohmann?json的基本使用教程

    c++中nlohmann?json的基本使用教程

    nlohmann/json 是一個(gè)C++實(shí)現(xiàn)的JSON解析器,使用非常方便直觀,下面這篇文章主要給大家介紹了關(guān)于c++中nlohmann?json基本使用的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-09-09
  • C++?Boost?ProgramOptions超詳細(xì)講解

    C++?Boost?ProgramOptions超詳細(xì)講解

    Boost是為C++語言標(biāo)準(zhǔn)庫提供擴(kuò)展的一些C++程序庫的總稱。Boost庫是一個(gè)可移植、提供源代碼的C++庫,作為標(biāo)準(zhǔn)庫的后備,是C++標(biāo)準(zhǔn)化進(jìn)程的開發(fā)引擎之一,是為C++語言標(biāo)準(zhǔn)庫提供擴(kuò)展的一些C++程序庫的總稱
    2022-11-11
  • 深入理解C++之策略模式

    深入理解C++之策略模式

    下面小編就為大家?guī)硪黄钊肜斫釩++之策略模式。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-06-06
  • C語言實(shí)現(xiàn)點(diǎn)菜系統(tǒng)

    C語言實(shí)現(xiàn)點(diǎn)菜系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)點(diǎn)菜系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • C/C++位操作實(shí)例總結(jié)

    C/C++位操作實(shí)例總結(jié)

    這篇文章主要介紹了C/C++位操作實(shí)例總結(jié),是C/C++程序設(shè)計(jì)中很重要的概念,需要的朋友可以參考下
    2014-08-08
  • 基于Opencv實(shí)現(xiàn)顏色識(shí)別

    基于Opencv實(shí)現(xiàn)顏色識(shí)別

    這篇文章主要為大家詳細(xì)介紹了基于Opencv實(shí)現(xiàn)顏色識(shí)別,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-07-07
  • C語言實(shí)現(xiàn)注冊(cè)登錄系統(tǒng)

    C語言實(shí)現(xiàn)注冊(cè)登錄系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)注冊(cè)登錄系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-12-12

最新評(píng)論