Post

c++变参函数模板

c++11的可变参函数模板

1. 可变参函数模板

1
2
3
4
template<typename... T>
void Print(T... args) {
  // ...
}

typename后面带上...表示这是一个可变参模板函数,可以接受任意数量的参数。

2. 展开方式

展开方式其实在11,17乃至之后都有不同的一些用法。

2.1 递归展开

1
2
3
4
5
6
7
8
9
10
template<typename T>
void Print(T value) {
  std::cout << "[" << value << "]\n";
}

template<typename T, typename... Args>
void Print(T value, Args... args) {
  std::cout << "[" << value << "]";
  Print(args...);
}

2.2 初始化列表展开

首先17的比较简单

1
2
3
4
template<typename... Args>
void Print(Args... args) {
  (std::cout << ... << args) << '\n';
}

11的稍微复杂一点

1
2
3
4
5
6
template<typename... Args>
void Print(Args... args) {
  int arr[] = {(std::cout << args, 0)...};
  (void)arr;
  std::cout << '\n';
}

其实这个是用到了initialize_list + ‘,’表达式的特性,arr数组的大小就是sizeof...(args)

初始化列表从左往右执行,所以保证了参数能够顺序展开,因为逗号表达式中,最后的结果取最后一个表达式的值,所以arr数组的值就是全0

你可以用std::initializer_list<int>{(std::cout << args, 0)...};来代替int arr[] = {(std::cout << args, 0)...};

1
2
3
4
5
template<typename... Args>
void Print(Args... args) {
  auto _ = std::initializer_list<int>{(std::cout << args, 0)...};
  std::cout << '\n';
}

然后看到了有6个’.’的那种,比较变态了,估计就写库用得到,放下C++ 形参包展开有 6 个点?

This post is licensed under CC BY 4.0 by the author.

Trending Tags