zoukankan      html  css  js  c++  java
  • Variadic Templates 可变参数模板

    Variadic Templates

    基础知识

    1 可变参数包,可以很方便的完成recursive function call(递归函数调用)

    2 typename... Types || const Types&... args || print(args...) 三个点的位置是语法规定,不必深究

    3 const Types&... args 整体表示可以传进去任意类型的任意参数,表示一个pack(包)

    4 sizeof...(args)计算pack中参数的数量

    5 ...就是一个所谓的pack(包)
    用于template parameters,就是template parameters pack(模板参数包)
    用于function parameter types,就是function parameter types pack(函数参数类型包)
    用于function parameters,就是function parameters pack(函数参数包)

    递归函数

    //没有这个函数,编译出错
    void print() 
    {// 边界条件,当args为0个时调用
    	cout << endl; 
    }    
    
    
    //typename... Types || const Types&... args || print(args...) 三个点的位置是语法规定,不必深究
    template < typename T, typename... Types/*模板参数包*/>
    //... args 表示可以传进去任意多个参数
    //Types表示类型,为模板,typename... Types表示类型可以是任意类型
    //const Types&... args 整体表示可以传进去任意类型的任意参数,表示一个pack(包)
    void print(const T& firstArg, const Types&... args/*函数参数包*/)
    {
    	//Inside variadic templates,sizeof...(args) yields tje number of arguments
    	//sizeof...(args)计算pack中参数的数量
    	//cout << sizeof...(args) << ",";
    	//打印第一个参数
    	cout << firstArg << ' ';
    	//递归调用剩下参数,args...表示包
    	print(args.../*函数参数包*/);
    }
    
    /*
    void print(const T& firstArg, const Types&... args) 与 void print(const Types&... args) 可以共存,可以编译通过。
    
    但前者比较特化,后者比较泛化,共存时永远不会调用后者。
    */
    template <typename... Types>
    void print(const Types&... args) {
    
    }
    
    int main()
    {
    	//第一次调用firstArg为7.5,args为 "hello", bitset<16>(377), 42
    	//第二次调用firstArg为hello,args为bitset<16>(377), 42
    	//第三次调用firstArg为bitset<16>(377),args为42
    	//第四次调用firstArg为42,args为空
    	//第五次调用参数列表为空,调用重载函数,打印换行
    	print(7.5, "hello", bitset<16>(377), 42);    // print "7.5 hello 0000000101111001 42"
        std::cout << "Hello World!
    ";
    }
    

    递归继承

    template <typename... Values> class tuple;
    template <> class tuple<> { };
    
    //private tuple <Tail...> 完成递归继承
    template <typename Head, typename... Tail>
    class tuple<Head, Tail...> : private tuple <Tail...> {
    	typedef tuple<Tail...> inherited;
    public:
    	tuple() { }
    	tuple(Head v, Tail... vtail) : m_head(v), inherited(vtail...) { }    // 调用base ctor
    	...
    protected:
    	Head m_head;
    };
    

    image-20210119223417113

    image-20210119223438724

  • 相关阅读:
    Android Listview 隐藏滚动条
    打开Activity时,不自动显示(弹出)虚拟键盘
    Spring Boot web API接口设计之token、timestamp、sign
    WPF ListView点击删除某一行并获取绑定数据
    WPF中控件的显示与隐藏
    WPF 格式化输出- IValueConverter接口的使用 datagrid列中的值转换显示
    WPF之DataGrid应用 翻页
    WPF中修改DataGrid单元格值并保存
    DataGrid获取单元格的值
    WPF DataGrid 列宽填充表格方法
  • 原文地址:https://www.cnblogs.com/LuckCoder/p/14300502.html
Copyright © 2011-2022 走看看