cpp variadic template

C++变长模板使用

C++11开始支持支持变长模板(variadic template),模板参数可以为任意多个, 变长模板参数用省略号来标识(…)。

变长模板参数通常以递归的形式打开(因此需要定义一个没有变长参数的base case模板),下面借用一个例子来说明:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>

template <typename Arg>
void Foo(Arg arg) {
std::cout << __PRETTY_FUNCTION__ << "\n";
}

template <typename First, typename... Args>
void Foo(First first, Args... args) {
std::cout << __PRETTY_FUNCTION__ << "\n";
Foo(first);
Foo(args...);
}

int main() {
std::string one = "one";
const char* two = "two";
Foo(one);
std::cout << std::endl;
Foo(one, two);
return 0;
}

上面代码的输出如下:

1
2
3
4
5
void Foo(Arg) [with Arg = std::__cxx11::basic_string<char>]

void Foo(First, Args ...) [with First = std::__cxx11::basic_string<char>; Args = {const char*}]
void Foo(Arg) [with Arg = std::__cxx11::basic_string<char>]
void Foo(Arg) [with Arg = const char*]

求和

下面尝试使用变长模板来实现一个求和的函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>

template <typename Arg>
Arg Sum(Arg arg) {
std::cout << __PRETTY_FUNCTION__ << "\n";
return arg;
}

template <typename First, typename... Args>
First Sum(First first, Args... args) {
std::cout << __PRETTY_FUNCTION__ << "\n";
return first + Sum(args...);
}

int main() {
std::cout << Sum(1, 2, 3, 4, 5) << std::endl;
return 0;
}

得到的结果如下:

1
2
3
4
5
6
First Sum(First, Args ...) [with First = int; Args = {int, int, int, int}]
First Sum(First, Args ...) [with First = int; Args = {int, int, int}]
First Sum(First, Args ...) [with First = int; Args = {int, int}]
First Sum(First, Args ...) [with First = int; Args = {int}]
Arg Sum(Arg) [with Arg = int]
15
/!-- -->