C++的可变参数模板函数

可变参数模板函数写法:

模板参数里写typename... args,表明args是一个可变参数。

之后再函数参数里args后面也要加...,以表示该参数为可变参数。

函数参数中对于args的修饰,会扩展到所有该args的参数,比如下面代码:

//可变参数模板函数使用方法1:递归调用,每次将可变参数规模变小直到为0
template<typename T>
void print(const T& x) {
    cout << "最后一次调用print,输出:" << x << endl;
}

template<typename T, typename... args>
void print(const T& x, const args&... rest) {
    cout << "当前print函数输出:" << x << endl;
    cout << "当前print函数的可变参数长度为:" << sizeof...(rest) << endl;
    print(rest...);
}

如果调用:int i=1,j=2,k=3;那么实际print(i,j,k)调用的是:print(const int& i,const int& j,const int& k);

//可变参数模板函数使用方法2:循环调用
template<typename... args>
void print2(args&&... li) {
    for (auto x : { li... }) {
        cout << x << endl;
    }
}
int main() {
    int i = 0, j = 1, k = 2;
    print2(i, j, k);
    getchar();
    return 0;
}

另外据C++primer上说,可变参数模板函数一般用来将它的参数转发给其他函数,比如:

template<typename... args>
void do_something(args... arg_list){
    //blahblahblah
}

template<typename... args>
void f(args&&... arg_list){ //这里arg后加了&&,将arg_list的所有参数都扩展为右值引用,方便接下来的转发
    do_something(std::forward<args>(arg_list)...);
}
int main(){
    int x1=1;
    const int x2=1;
    const int& x3=x2;
    int* x4=&x1;
    int&& x5=move(x1);
    f(x1,x2,x3,x4,x5,move(x1),1);
    getchar();
    return 0;
}

正好复习下转发:

f函数实际调用的样子是这样的:

可以看到完美转发的强大之处。。。所有的const、左右值、引用/指针性质全部原封不动转发给了do_something函数。

原文地址:https://www.cnblogs.com/FdWzy/p/12602424.html

时间: 2024-10-02 20:44:37

C++的可变参数模板函数的相关文章

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

c++11 可变参数模板函数 #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <string> #include <vector> #include <map> // 在C++11之前,类模板和函数模板只能含有固定数量的模板参数.C++11增强了模板功能,允许模板定义中包含0到任意个模板参数,这就是可变参数模板. // 可变参数模板和普通模板的语义是一样的,只是写法上稍有区别,声明可变

第21课 可变参数模板(2)_展开参数包

1. 可变参数模板函数 (1)递归函数方式展开参数包 ①一般需要提供前向声明.一个参数包的展开函数和一个递归终止函数. ②前向声明有时可省略,递归终止函数可以是0个或n个参数 (2)逗号表达式和初始化列表方式展开参数包 ①逗号表达式按顺序执行,返回最后一个表达式的值. ②initilizer_list可接受任意多个不同类型的参数. ③借助逗号表达式来展开包,并将返回的结果用于初始化initilizer_list. [编程实验]展开可变参数模板函数的参数包 #include <iostream>

C++ 11 可变参数模板和 boost::any 实现可变参数函数

1 class SqlHelper 2 { 3 public: 4 template <typename... Params> 5 static bool preparedExecute(sql::PreparedStatement* pstmt, Params... parameters) 6 { 7 return doPreparedExecute(pstmt, 1, parameters...); 8 } 9 10 private: 11 template <typename...

可变参数模板用法

//可变参数模板 //可变参数模板,可以创建可接受可变数量参数的模板函数和模板类 //本程序通过模板函数来实例一下可变参数模板的基本用法 #include<iostream> using namespace std; void one(){}//当最后一个参数传完后,需要一个无参的重载版本 template <typename T>//当只剩最后一个参数时,编译器优先选择此模板,这样最后一个输出后面就没有逗号了 void one(T v) { cout << v <

c++11可变参数模板的使用1

1.概述 C++11的新特性--可变模版参数(variadic templates)是C++11新增的最强大的特性之一,它对参数进行了高度泛化,它能表示0到任意个数.任意类型的参数.相比C++98/03,类模版和函数模版中只能含固定数量的模版参数,可变模版参数无疑是一个巨大的改进.然而由于可变模版参数比较抽象,使用起来需要一定的技巧,所以它也是C++11中最难理解和掌握的特性之一. 虽然掌握可变模版参数有一定难度,但是它却是C++11中最有意思的一个特性,本文希望带领读者由浅入深的认识和掌握这一

C++反射机制:可变参数模板实现C++反射

1. 概要   本文描述一个通过C++可变参数模板实现C++反射机制的方法.该方法非常实用,在Nebula高性能网络框架中大量应用,实现了非常强大的动态加载动态创建功能.Nebula框架在coding.net的仓库地址.   C++11的新特性--可变模版参数(variadic templates)是C++11新增的最强大的特性之一,它对参数进行了高度泛化,它能表示0到任意个数.任意类型的参数.关于可变参数模板的原理和应用不是本文重点,不过通过本文中的例子也可充分了解可变参数模板是如何应用的.

第20课 可变参数模板(1)_模板参数包和函数参数包

1.  参数包(parameter pack) (1)模板参数包(以tuple为例):template<typename- Elements>class tuple ①Elements标识符的左侧使用了省略号,在C++11中Elements被称为"模板参数包",表示可以接受任意多个参数作为模板参数. ②编译器将多个模板参数打包成"单个"的模板参数包,如tuple<int, char, double>实例化模板类时,Element就是包含int

2.类型不一致可变参数模板与类型一致函数模板

//类型不一致函数模板 1 #include <iostream> 2 #include <cstdarg> 3 using namespace std; 4 5 void show() 6 { 7 8 } 9 10 //参数类型不一致,个数不确定 11 template<typename T,typename...Args>//typename...Args可变参数 12 void show(T t, Args...args)//args如果没结束就当做T t,Arg

第23课 可变参数模板(4)_Optional和Lazy类的实现

1. optional类的实现 (1)optional的功能 ①optional<T>的内部存储空间可能存储了T类型的值,也可能没有.只有当optional被T初始化之后,这个optional才是有效的.否则是无效的.它实现了未初始化的概念. ②optional可以用于解决函数返回无效值的问题.当函数返回一个未初始化的Optional对象时,表明函数正确执行了,只是结果不是有用的值. ③举例:optional<int> op; //未被初始化. optional<int>