在C++11之前, 有两个典型的受制于模板功能不强而导致代码重复难看的问题, 那就 function object 和 tuple。 拿 function objects 来说, 需要一个返回类型参数及N个参数类型参数。 但因为变长参数模板不受支持,导致不得不重复书写7、8个模板类,但最终也只能支持7、8个参数的 function object。C++11中最终为我们带来了强大的变长 参数模板功能,这些问题也随之迎刃而解了。

可变参数模板(Variadic Template)故名思义,即可以接受任意数量参数的类/函数模板。 其声明方式为

template<typename... Args>
class VariadicTemplate;

当然non-type参数也是支持的比如 template<int... Args> class VariadicIntTemplate;

这里Args代表0-N个类型参数,也就是说VariadicTemplate<>也是有效的模板实例。

C++11 翻新了省略号(...)操作符来支持对这种模板参数的访问及使用。

类型展开

将所有模板参数展开在当前位置,用来调用其它模板、声明函数指针类型

template<typename ...Args>
int foo() {
int (*p)(Args...) = bar<Args...>;
p(, 0.5);
return bar<Args...>(, 0.5);
}

对于 foo<int, float> 实例,其 p 的类型为 int (*)(int, float) 而 return 语句将调用 bar<int, float>(1, 0.5)

此外还可以展开类型参数用来指定基类列表

template<typename... Args>
class foo : Args...{
}; foo<bar, barz> f; // 该类继承 bar, barz 两个基类

Parameter Packs / Initialization Lists

通过省略号操作符可以声明参数包,这些参数包可以在函数的参数位置展开。

template<typename ...Args>
void foo(Args... args) {
}

当使用 foo<int, float> 时,其有两参数,一个整数,一个float,因此调用方法为 foo<int, float>(1, 0.1f);

此外还可以将参数包展开到构造函数的初始化列表

template<typename... Args>
class foo : Args...{
public:
foo(Args...args):Args(args)...{
}
}; foo<bar, barz> f(bar(), barz());

sizeof... operator

要获取模板变长参数的实参长度,使用 sizeof... 运算符,它也可以被用于 Parameter Packs

template<typename ... Args>
size_t foo() {
return sizeof...(Args);
}
template<typename ... Args>
size_t fooz(Args ...args) {
return sizeof...(args);
}

以上就是变长参数的基本用法,但真正发挥作用,往往还要借助模板特化 (Template Specialization)

可变参数模板与模板特化

可变参数模板与普通模板一样,可以进行特化,从而实现一些有意义的模式

template<typename ... Args>
void output(Args ... args) {
}
template<typename Arg0, typename ... Args>
void output(Arg0 arg0, Args ... args) {
std::cout << arg0;
output<Args...>(args...);
}
template<>
void output() {
} /*------------------------------*/
typedef decltype(std::cout) cout_type;
auto endl = std::endl<cout_type::char_type, cout_type::traits_type>;
output(, 0.3, (void*)nullptr, "string", 'c', endl);

以上代码输出

10.30stringc

C++11 可变参数模板的更多相关文章

  1. c++11——可变参数模板

    在c++11之前,类模板和函数模板只能含有固定数量的模板参数,c++11增加了可变模板参数特性:允许模板定义中包含0到任意个模板参数.声明可变参数模板时,需要在typename或class后面加上省略 ...

  2. C++ 11可变参数接口设计在模板编程中应用的一点点总结

    概述 本人对模板编程的应用并非很深,若要用一句话总结我个人对模板编程的理解,我想说的是:模板编程是对类定义的弱化. 如何理解“类定义的弱化”? 一个完整的类有如下几部分组成: 类的名称: 类的成员变量 ...

  3. [C++11]C++可变参数模板

    可变参数模板 原文链接: http://blog.csdn.net/xiaohu2022/article/details/69076281 普通模板只可以采取固定数量的模板参数.然而,有时候我们希望模 ...

  4. c++ 可变参数模板

    可变参数模板,自己尝试了个例子,如下: // variadicTemplates.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #incl ...

  5. C++11新特性之五——可变参数模板

    有些时候,我们定义一个函数,可能这个函数需要支持可变长参数,也就是说调用者可以传入任意个数的参数.比如C函数printf(). 我们可以这么调用. printf(); 那么这个函数是怎么实现的呢?其实 ...

  6. C++ 标准库,可变参数模板。可变参数数量,可变参数类型【转】

    #include <iostream> // 可变模板参数 // 此例:可以构造可变数量,可变类型的函数输入. // 摘自:https://www.cnblogs.com/qicosmos ...

  7. C++学习之可变参数的函数与模板

    所谓可变参数指的是函数的参数个数可变,参数类型不定的函数.为了编写能处理不同数量实参的函数,C++11提供了两种主要的方法:如果所有的实参类型相同,可以传递一个名为initializer_list的标 ...

  8. C++ 实现可变参数的三个方法

    有时我们无法提前预知应该向函数传递几个实参.例如,我们想要编写代码输出程序产生的错误信息,此时最好用同一个函数实现该项功能,以便对所有错误的处理能够整齐划一.然而,错误信息的种类不同,所以调用错误输出 ...

  9. c++之可变参数格式化字符串(c++11可变模板参数)

    本文将使用 泛型 实现可变参数. 涉及到的关见函数:  std::snprintf 1.一个例子 函数声明及定义 1 // 泛型 2 template <typename... Args> ...

随机推荐

  1. MVC模式实现登录以及增删改查之登录(一)

    我在这里用的不是maven项目,用的一般的web项目,所以需要用到的架包需要自己去下载添加,在项目中,一定注意环境的配置,我用的是jre1.7 1  新建项目 2  建立好MVC的管理包,导入对应的架 ...

  2. Java基础知识强化之集合框架笔记03:Collection集合的功能概述

    1. Collection功能概述:Collection是集合的顶层接口,它子体系有重复的,有唯一性,有有序的,无序的. (1)添加功能 boolean add(Object obj):添加一个元素 ...

  3. Java基础知识强化之IO流笔记14:递归之输出指定目录下所有java文件绝对路径的案例

    1. 需求:输出指定目录下的所以.java结尾文件的绝对路径的案例:  分析:  A:封装目录  B:获取该目录下的所有文件和文件夹的File数组  C:遍历这个File数组,得到每一个File对象的 ...

  4. 9.7noip模拟试题

    题目名称 日历游戏 最大公约数 密码 英文代号 calendar gcd pasuwado 输入文件名 calendar.in gcd.in pasuwado.in 输出文件名 calendar.ou ...

  5. ASP.NET5配置

    ASP.NET5支持各种各样的配置,应用程序配置数据可以来自JSON, XML或者INI格式的文件,也能来自环境变量,你也可以自定义你自己的Configuration Provider. 1. 获取和 ...

  6. Asp.net IsPostBack

    Page.IsPostBack是一个标志:当前请求是否第一次打开.调用方法为:Page.IsPostBack或者IsPostBack或者this.IsPostBack或者this.Page.IsPos ...

  7. 【COGS1384】鱼儿仪仗队

    [题目描述] Jzyz的池塘里有很多条鱼,鱼儿们现在决定组成一个仪仗队.现在备选的N(1 <= N <= 100,000)条鱼排成了一条直线,并且按照亲近关系排的队伍,鱼儿的顺序不能改变, ...

  8. 实时错误 '91' :对象变量或with块变量未设置

    大家这几天在做学生信息管理系统的时候,出现最多的应该就是这个问题了,“实时错误‘91’:对象变量或with块变量未设置”.如右图: 遇到这个问题,我们首先应该去参考MSDN,不过这时候MSDN似乎没有 ...

  9. hibernate的get、load的方法的区别,IllegalArgument异常

    关于hibernate中的load,get,以及延迟加载问题 今天在使用hibernate时,发现一异常: could not initialize proxy - no Session 查询资料之后 ...

  10. 或许是python yield最好的答案 ?

    地址:http://pyzh.readthedocs.org/en/latest/the-python-yield-keyword-explained.html#yield 译者: hit9 原文: ...