【C++ 模板】 可变参数模板

可变参数模板

一个可变参数模板就是一个接受可变数目参数的模板函数或模板类,可变数目的参数称作参数包 存在两种参数包:

  • 模板参数包,表示零个或多个模板参数
  • 函数参数包, 表示零个或多个函数参数

使用原型:

template <typename T, typename ... Args> 
void fun(T t, Args ... args);// 合法 

template <typename ... Args, typename T> 
void fun(Args ... args, T t);// 非法

 

与往常一样,编译器从函数的实参推断模板参数类型。对于一个可变参数模板,编译器还会推断包中参数的数目。例如, 给定下面的调用:

// Args是一个模板参数包; rest是一个函数参数包
// Args表示零个或多个模板类型参数
// rest表示林个或多个函数参数
template <typename T, typename ... Args>
void foo(const T &t, const Args& ... rest)

int i = 0; double  d = 3.14; strng s = "how now brown cow";
foo(i, s, 42, d);
foo(s, 42, "hi");
foo(d, 42);
foo("hi");

编译器会为foo 实例化出四个不同的版本:

void foo(const int&, const string&, const int&, const double&);
void(const string&, const int&, const char[3]&);
void foo(const double&, const string&);
void foo(const char[3]&);

 

二、sizeof...运算符

【注意】当我们需要知道包中有多少个元素时,可以用sizeof...

#include<iostream>
#include<string>
using namespace std;

template <typename T, typename ... Args>
void foo(const T&, const Args& ... rest)
{
    cout << sizeof...(Args) << " ";  //模板类型参数的数目
    cout << sizeof...(rest) << endl; // 函数参数的数目
}

int main()
{
    int i = 0; double  d = 3.14; string s = "how now brown cow";
    foo(i, s, 42, d);
    foo(s, 42, "hi");
    foo(d, 42);
    foo("hi");

    return 0;
}

运行结果:

【C++ 模板】 可变参数模板

 

 

1. 示例:非可变参数模板比可变参数模板更特例化,因此编译器选择非可变参数版本。

#include<iostream>
#include<string>
using namespace std;

template <typename T>
ostream& print(ostream &os, const T &t)
{
    return os << t << endl;
}

template <typename T, typename ... Args>
ostream &print(ostream &os, const T &t, const Args& ... rest)
{
    os << t << " , ";
    return print(os, rest ...);
}

int main()
{
    int i = 0;
    string s = "hello";

    print(cout, i);
    print(cout, i, s);
    print(cout, i, s, 42.1, 'A', "End");
    return 0;
}

运行结果:

【C++ 模板】 可变参数模板

 

练习16.55

【C++ 模板】 可变参数模板

 

 

四、包扩展

#include <iostream>
using namespace std;

template <typename T>
T accum(const T &t)
{
    return t;
}

template <typename T, typename... Args>
T accum(const T &t, Args... args)
{
    return t + accum(args...);
}

int h()
{
    return 42;
}

template <typename ...Args>
int h(int t, Args ... args)
{
    return t + h(args...);
}

void f(int i, int j = 0, int k = 0, int l = 0)
{
    cout << i << " + "
        << j << " + "
        << k << " + "
        << l << " =  "
        << i + j + k + l << endl;
}

template<typename ... Args>
void g(Args ... args)
{
    cout << sizeof...(Args) << endl;
    cout << sizeof...(args) << endl;
    // h(a1, a2, a3, ..., an)
    f(args...);
    // h(a1, a2, a3, ..., an)
    cout << h(args...) << endl;
    //f(h(a1), h(a2), h(a3), ..., h(an))
    f(h(args) ...);
    // f(h(a1, a2, a3, ..., an2)
    f(h(args ...));
    // f(h(5,6,7,8) + a1, h(5,6,7,8) + a2, h(5,6,7,8) + a3, ..., h(5,6,7,8) + an)
    f(h(5, 6, 7, 8) + args ...);
}

int main()
{
    cout << accum(1, 2, 3, 4) << endl;
    g(1, 2, 3, 4);
    return 0;
}

 

运行结果:

【C++ 模板】 可变参数模板

 

 

 

 

原文链接: https://www.cnblogs.com/sunbines/p/9087283.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    【C++ 模板】 可变参数模板

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/274619

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月15日 上午12:28
下一篇 2023年2月15日 上午12:29

相关推荐