C 11新特性之變長引數模板詳解

2022-09-24 17:18:16 字數 1673 閱讀 8123

目錄

在c++11之前,無論是類模板 還是函式模板,都只能按其指定的樣子,接受一組固定數量的模板引數;

這已經大大提公升了**的復用!

在c++11之後,加入了新的表示方 法,允許任意個數、任意類別的模板引數,同時也不需要在定義時將引數的個數固定。更加像」黑魔法「了。

template class magic;

模板類程式設計客棧 magic 的物件,能夠接受不受限制個數的 typename 作為模板的形式引數,例如下面的定義:

class magic,

std::map<:string std::vector class="tzyzgonsfm">>> darkmagic;

既然是任意形式,所以個數為 0 的模板引數也是可以的:class magic<> nothingwww.cppcns.com;。 如果不希望產生的模板引數個數為 0,可以手動的定義至少乙個模板引數:

template class magic;

除了在模板引數中能使用 ... 表示不定長模板引數外,函式引數也使用同樣的表示法代表不定長引數。

傳統 c 中的 printf 函式,雖然也能達成不定個數 的形參的呼叫,但其並非類別安全。而 c++11 除了能定義類別安全的變長引數函式外,還可以使類似 printf 的函式能自然地處理非自帶類別的物件。除了在模板引數中能使用 ... 表示不定長模板引數外, 函式引數也使用同樣的表示法代表不定長引數,這也就為我們簡單編寫變長引數函式提供了便捷的手段, 例如:

template

void printf(const std::string &str, args... args);

其中,args 與 args 分別代表模板與函式的變長引數集合, 稱之為引數包 (parameter pack)。引數包必須要和運算子"..."搭配使用。

長引數模程式設計客棧板中,變長引數包無法如同一般引數在類或函式中使用;這個很好理解!

因為在棧中,我們需要先知道函式有多少個引數,才可以入棧,但是我們不知道變長引數有多長,所以需要特殊手法!

首先,我們可以使用 sizeof... 來計jznlijx算引數的個數,:

template

void magic(ts... args)

遞迴去獲得所有引數,是非常容易想到的方法,這種方法不斷遞迴地向函式傳遞模板引數,進而達到遞迴遍歷所有模板引數的目的。

printf 會不斷地遞迴呼叫自身:函式引數包 args... 在呼叫時, 會被模板類別匹配分離為 t value和 args... args。 直到 args... 變為空引數,則會與簡單的 printf(const char *s) 形成匹配,退出遞迴。

//遞迴模板函式

template

void printf1(t0 value)

template

void printf1(t value, ts... args)

int recursivetemplatefunc()

上面的遞迴很容易理解,但是比較繁瑣,那麼還有沒有什麼好方法呢?

在 c++17 中增加了變參模板展開的支援,於是你可以在乙個函式中完 成 printf 的編寫:

//變參模板展開

template

void printf2(t0 t0, t... t)

模板作為c++中的」黑魔法「般的**,學起來比較難,但當掌握後,確實非常高階,變長引數模板對我們寫模板有很大的幫助!

c 11變長引數函式模板

by francis hao mar 25,2018 乙個最簡單的例項大概是這個樣子 include usingnamespacestd 變長引數函式模板宣告 template typename.t voidprint t.val 邊界條件 voidprint void 遞迴的特例化定義 templ...

C 11的模板新特性 變長引數的模板

這個特性很讚,直接給例子吧,假如我要設計乙個類,cachedfetcher內部可能使用std map也可能使用std unordered map,也可能是其它的map,怎麼設計呢?沒有c 11變長模板之前這很費勁。因為map的模板引數可不是只有key,value兩個啊,還有一些有預設引數的templ...

走進C 11(十四)變長引數模板

解釋 c 03只有固定模板引數。c 11 加入新的表示法,允許任意個數 任意類別的模板引數,不必在定義時將引數的個數固定。變長模板 變長引數是依靠c 11新引入的引數包的機制實現的。templatestruct tuple tuple t0 types不含任何實參tuplet1 types含有乙個實...