C 可變參模板

2021-10-13 01:33:29 字數 4530 閱讀 4136

可變引數模板是乙個接受可變數目引數的模板函式或模板類,在模板引數列表中,typename…指出接下來的引數表示0個或多個型別的列表,乙個型別名後面跟省略號表示0個或多個給定型別的非型別引數的列表。在函式引數列表中,如果乙個引數的型別是乙個模板引數包,則此引數也是乙個函式引數包。

可變引數模板通常是遞迴的,第一步呼叫處理包中的第乙個實參,然後用剩餘實參呼叫自身, sizeof…運算子可以獲得包中元素數量。

如果需要用引數包中的引數,則一定要將引數包展開。有兩種展開引數包的方法:

(1)通過遞迴的模板函式來將引數包展開

(2)通過逗號表示式和初始化列表方式展開引數包

template

<

class..

. t>

void

f(t.

.. args)f(

);//0f(1

,2);

//2f(1

,2.5,""

);//3

**

namespace a

template

<

typename t,

typename..

. u>

void

func2

(const t& a,

const u&..

.args)

//注意引用型別符的位置

}int

main()

注意:

t 理解成0到多個不同的型別,那對應的引數args也應該是多個不同型別的引數。

引數包中可以容納0 到多個模板引數,而且模板引數可以為任意的型別。

在具體函式形參中,&的位置,出現在型別名的後面。

#include

using

namespace std;

//遞迴終止函式

void

print()

//引數包展開函式

template

<

classt,

class..

.args>

void

print

(t head, args.

.. rest)

intmain

(void

)

通過type_traits來展開並列印引數包 沒寫呢

template

<

class

t>

void

printarg

(t t)

template

<

class..

.args>

void

expand

(args.

.. args);}

expand(1

,2,3

,4);

std::tuple就是乙個可變模板類,template class tuple;

可變引數模板類的引數包展開的方式:

namespace b

;//主模板

template

<

>

class

myclass

<

>};

template

<

typename first,

typename..

. others>

class

myclass

>

:private myclass>

//偏特化

myclass

(first p, others.

..q)

:_first

(p), myclass>

(q...)

first _first;};

}int

main()

//整型序列的定義

template

<

int...

>

struct indexseq

;//繼承方式,開始展開引數包

template

<

int n,

int.

.. indexs>

struct makeindexes:makeindexes1,n-

1,indexes...

>

;//模板特化,終止展開引數包的條件

template

<

int.

.. indexs>

struct makeindexes<

0,indexes...

>

;int

main()

namespace b

;//主模板

template

<

>

class

myclass

<

>};

template

<

typename first,

typename..

. others>

class

myclass

>

myclass

(first p, others.

..q)

:_first

(p),

_o(q...

) first _first;

myclass> _o;

//組合關係(復合關係)};

}int

main()

這種展開引數包的方式需要寫類的特化版本。

實現思路:計數器從0 開始,每處理乙個引數,計數器就 +1 ,一直到把所有引數處理完,最後用模板偏特化,作為遞迴呼叫結束。

namespace b};

//需要乙個特化版本,用於結束遞迴呼叫

template

<

int maxcount,

typename..

.t>

class

test

>};

template

<

typename..

. t>

void

func

(const tuple>

&t)//可變引數函式模板

}int

main()

c++11引數包展開

模板引數就是模板的引數,我們一般指定為t型別,實際上可以使用任何的名字,例如指定乙個foo的模板引數:

temlate<

typename foo>

foo calc

(const foo& a,

const foo& b)

而模板模板引數則是模板的引數又是乙個模板,例如:

template

<

typename t,

template

<

typename u>

typename container>

class

xcls

;

模板的第乙個引數是t型別,第二個引數是乙個container,他是乙個可以指定乙個u型別的變數。

那麼如何使用他呢?

template

<

typename t>

class

test

;int

main

(void

)

我們可以定義乙個模板類,然後將其如上方式傳入就可以了。

但是如果傳入乙個容器呢?比如:list

xcls mylst1;
如果編譯就會報錯。我們分析一波:

將string 和 list傳入到類xcls中,然後就會定義乙個list的c變數,這樣看起來是可以的,因此我們使用list容器的時候就是list《乙個型別》,但是這裡為什麼就不行呢?是因為list容器實質上是有第二引數的,雖然第二引數有預設的引數,正如我們平常使用的那樣,只需要指定乙個引數,但是在這裡無法通過編譯,因此,我們使用如下解決辦法:

template

<

typename t>

using lst = std::list>

;xcls mylst2;

// 編譯時需要加上std=c++11

使用c++11的using關鍵字的新功能,來定義乙個型別的別名,而且使用在模板的情況下,因此我們編譯時要指定std=c++11

然後我們將list的別名lst傳入進入,就可以編譯通過。

泛型的列印函式

工廠函式

可變參模板模板模板引數

include include include include include include include include using namespace std namespace nmsp1 classa template typename.args class myclasst 主模板 t...

可變參模板template

普通模板只可以採取固定數量的模板引數。然而,有時候我們希望模板可以接收任意數量的模板引數,這個時候可以採用可變引數模板。對於可變引數模板,其將包含至少乙個模板引數包,模板引數包是可以接收0個或者多個引數的模板引數。相應地,存在函式引數包,意味著這個函式引數可以接收任意數量的引數。乙個可變引數類模板定...

可變參模板續 模板模板引數

include include include include include using namespace std 從類模板引入 template t u叫模板引數,更具體叫型別模板引數 前面有typename template typename t,型別模板引數 template class ...