C++0x尝鲜:Variadic Function Templates(带变长参数的函数模板)
来源:互联网 发布:北京现代软件学院 图片 编辑:程序博客网 时间:2024/04/30 14:08
关于变长参数模板(Variadic Templates)
在C++0x之前,模板(包括类模板和函数模板)参数的个数和类型是固定不变的,而且都必须在定义时预先确定。在C++0x中,这一点得到了改善,模板(无论类模板还是函数模板)将具有指定任意个数任意类型参数的能力,这就是所谓的变长参数模板(Variadic Templates)。下面我们就用代码说明带变长参数的函数模板。
C++代码
#include <iostream>using namespace std;template<typename T>void output(T&& value){ cout << value << endl;}template<typename First, typename... Rest>void output(First&& first, Rest&&... rest){ cout << first << ","; output(forward<Rest>(rest)...);}template<typename T>T sum(T&& value){ return value;}template<typename First, typename Second, typename... Rest>First sum(First&& first, Second&& second, Rest&&... rest){ return sum(first + second, forward<Rest>(rest)...);}int main(){ double d = 2.3; output(42,"hello",d,'a'); output("hello",d,'a'); output(d,'a'); output('a'); output(sum(1), sum(1, 2), sum(1, 2, 3)); return 0;}//42,hello,2.3,a//hello,2.3,a//2.3,a//a//1,3,6
代码说明
- 代码中的 output 与 sum 是两个可接受变长参数的函数模板。
output 函数接受一个及以上的参数,函数功能为输出各个参数的值。
sum 函数同样接受一个及以上的参数,函数功能为计算各个参数的和。 - 代码中output 函数有两个版本。
- 参数只有一个时调用4~8行所定义的非递归版本,
此版本参数个数固定,C++11之前即已合法。 - 参数有两个及以上时调用9~14行所定义的递归版本,
此版本参数个数可变,依赖C++11新增的语言特性。 - 代码第9行模板参数列表中的 typename... Rest 部分被称作模板参数包
实际调用时模板参数包 Rest 内将存放可变长部分各参数(第1个参数first之后的所有参数)的类型
如第30行用 output(42,"hello",d,'a'); 调用时,Rest 的内容为(char*, double&, char) - 代码第10行函数参数列表中的 Rest&&... rest 部分被称作函数参数包
实际调用时函数参数包 rest 内将存放可变长部分各参数(第1个参数first之后的所有参数)的值
如第30行用 output(42,"hello",d,'a'); 调用时,rest 的内容为("hello",d,'a') - 代码第13行中的...被称为解包运算符,
实际调用时解包运算符将把它之前的表达式(即forward<Rest>(rest))作为模板来展开
模板参数包Rest 以及函数参数包rest,展开之后所生成的各表达式将用逗号连接,
如第30行用 output(42,"hello",d,'a'); 调用时,forward<Rest>(rest)... 将被展开为
forward<char*>("hello"), forward<double&>(d), forward<char>('a') - 由以上分析可知
递归版本的output函数输出第一个参数first的值以及逗号之后用剩余参数递归调用自身,
非递归版本的output函数则只输出唯一一个参数value的值,不会输出逗号。 - 第30行用 output(42,"hello",d,'a'); 调用时模拟运行结果如下
output(42,"hello",d,'a')
= 输出"42,“ 之后调用 output(forward<char*>("hello"), forward<double&>(d), forward<char>('a'))
= 输出"42,“ 之后调用 output("hello", d, 'a')
= 输出"42,hello,“ 之后调用 output(forward<double&>(d), forward<char>('a'))
= 输出"42,hello,“ 之后调用 output(d, 'a')
= 输出"42,hello,2.3,“ 之后调用 output(forward<char>('a'))
= 输出"42,hello,2.3,“ 之后调用 output('a')
= 输出"42,hello,2.3,a“
注意最后一步调用非递归版本,因而没有输出逗号。 - 与output 函数相类似,sum 函数同样有两个版本
重复以上分析可知
递归版本的sum 函数计算前两个参数first及second的和之后使用计算结果与剩余参数递归调用自身,
非递归版本的sum 函数则返回唯一一个参数value的值。 - 第34行用 sum(1,2,3); 调用时模拟运行结果如下
sum(1,2,3)
= sum(1+2, forward<int>(3))
= sum(1+2, 3)
= sum(1+2+3)
= 1+2+3
= 6
- C++0x尝鲜:Variadic Function Templates(带变长参数的函数模板)
- C++0x尝鲜:Variadic Function Templates(带变长参数的函数模板)
- C++11尝鲜:Variadic Function Templates(带变长参数的函数模板)(续)
- 可变参数模板(Variadic Templates)
- C/C++变长参数宏(Variadic Macros)
- C++ - 可变参数函数模板(Variadic Function Template) 详解 及 代码
- C++ 函数模板( Function templates)
- C++0x 学习笔记之 Variadic Templates
- variadic template (可变参数模板)
- C++可变长参数模版(Variadic Templates)
- 函数的变长参数
- 变长参数的函数
- 变长参数的函数
- Function Templates 函数模板——初窥
- C的变长参数
- Variadic templates
- C语言函数 变长参数
- c语言变长参数函数
- python 函数
- MySQL服务器启动
- CSDN Blog 右下角广告过滤方法
- C++实现Behavioral - Memento模式
- 七、Qt Creator实现文本查找
- C++0x尝鲜:Variadic Function Templates(带变长参数的函数模板)
- MySQL数据库安装
- 八、Qt Creator实现状态栏显示
- rpm命令手册
- 基于linux的3款压力测试工具:Siege,webbench,ab
- RPM命令手册
- [经典]Linux内核中get_free_page、kmalloc和vmalloc函数的区别(示例Module)
- linux下安装软件详解
- ps命令详解