可變引數模板是乙個接受可變數目引數的模板函式或模板類,在模板引數列表中,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 ...