剖析C++中的常量表达式与省略号的相关作用

2020-01-06 14:22:09于海丽

模板参数列表(template <parameter-list>), typename... 介绍了模板参数包。
在参数声明语句(func(parameter-list)),“顶层”省略号介绍函数参数包,并且该省略号地位是很重要的


// v1 is NOT a function parameter pack:
template <typename... Types> void func1(std::vector<Types...> v1); 

// v2 IS a function parameter pack:
template <typename... Types> void func2(std::vector<Types>... v2); 

如果省略号在参数名之后出现,则具有参数 pack 展开。
一种阐明 variadic 模板功能框架的好方法是在 printf 一些功能的重新写入中使用:


#include <iostream>

using namespace std;

void print() {
  cout << endl;
}

template <typename T> void print(const T& t) {
  cout << t << endl;
}

template <typename First, typename... Rest> void print(const First& first, const Rest&... rest) {
  cout << first << ", ";
  print(rest...); // recursive call using pack expansion syntax
}

int main()
{
  print(); // calls first overload, outputting only a newline
  print(1); // calls second overload

  // these call the third overload, the variadic template, 
  // which uses recursion as needed.
  print(10, 20);
  print(100, 200, 300);
  print("first", 2, "third", 3.14159);
}

Output


1
10, 20
100, 200, 300
first, 2, third, 3.14159

注意
合并变参数模板函数的大多数实现使用某种形式的递归,但是它与传统递归稍有不同。传统递归涉及使用与函数相同的签名调用函数。(可以重载或模板化,但每次都要选择相同的签名。)可变递归使用不同(几乎总是减少)数目的参数调用可变函数模板,因此每次都抹去不同的签名。仍需要“基用例”,但是,递归性质是不同的。



注:相关教程知识阅读请移步到C++教程频道。