程序猿的自我修养 Weilit

C++11泛型编程

2019-11-19

C++11泛型编程

可变参数模板

reference:

c++11可变参数模板类
c++可变参数模板
c++ typeid关键字详解

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

// 在C++11之前,类模板和函数模板只能含有固定数量的模板参数。C++11增强了模板功能,允许模板定义中包含0到任意个模板参数,这就是可变参数模板。

// 可变参数模板类的展开一般需要定义2 ~ 3个类,包含类声明和特化的模板类

// -------------例1-------------
// 可变参数模板类 继承方式展开参数包
template<typename... A> class BMW{};  // 变长模板的声明

template<typename Head, typename... Tail>  // 递归的偏特化定义
class BMW<Head, Tail...> : public BMW<Tail...>
{//当实例化对象时,则会引起基类的递归构造
public:
    BMW()
    {
        printf("type: %s\n", typeid(Head).name());  // typeid关键字,类似于sizeof这类的操作符
                    // typeid(变量).name()运行时获得变量的类型名称
                    // 判断类型:int a; typeid(a) == typeid(int)
                    // reference: https://blog.csdn.net/gatieme/article/details/50947821
    }

    Head head;
};

template<> class BMW<>{};  // 边界条件


// -------------例2-------------
// 可变参数模板结构体 模板递归和特化方式展开参数包
template <long... nums> struct Multiply;// 变长模板的声明

template <long first, long... last>
struct Multiply<first, last...> // 变长模板类
{
    static const long val = first * Multiply<last...>::val;
};

template<>
struct Multiply<> // 边界条件
{
    static const long val = 1;
};


// -------------例3-------------
// 可变参数模板函数 递归方式展开参数包
// 处理每个类型的实际函数
void handleValue(int value) { cout << "Integer: " << value << endl; }
void handleValue(double value) { cout << "Double: " << value << endl; }
void handleValue(string value) { cout << "String: " << value << endl; }

// 用于终止迭代的基函数(边界条件)
template<typename T>
void processValues(T arg)
{
    handleValue(arg);
}

// 可变参数函数模板
template<typename T, typename ... Ts>
void processValues(T arg, Ts ... args)
{
    handleValue(arg);
    processValues(args ...); // 解包,然后递归
}


void mytest()
{
    BMW<int, char, float> car;
    /*
    运行结果:
        type: f
        type: c
        type: i
    */

    std::cout << Multiply<2, 3, 4, 5>::val << std::endl; 
    // 运行结果:120

    processValues(1, 1.1, "str");
    /* 运行结果:
        Integer: 1
        Double: 1.1
        String: str
    */
    return;
}


int main()
{
    mytest();

    // system("pause");        // 在命令行调用"pause"命令:输出"请按任意键继续.."并等待用户按键
    return 0;
}

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!

¥ 打赏博主

上一篇 git常用命令

留言