C++学习之第十五天-模板与泛型编程

知识点总结

1.函数模板-泛型编程,类型参数化:template<typename/class T>,typename和class效果一样

    1.T是一个通用的数据类型,告诉编译器如果下面紧跟着的函数或者类中出现T,不要报错

2.模板的使用

            1.自动推导类型,编译器必须推导出一致的T数据类型,才能正常使用函数模板。

            2.显式指定模板类型:mySwap<int>(a,b)

            3.模板不能单独使用,必须指定出T的类型才可以用

            4.类模板的声明和实现不能分文件进行,必须写到一起,和内联函数一样,否则会链接失败。

3.函数模板和普通函数的区别以及调用规则
    1.区别:对于函数模板,编译器进行隐式推导类型的时候,只能识别一致的T类型.
           对于普通函数,可以之间进行隐式转换。
    2.调用规则:
           1.优先调用普通函数,如果想强制调用函数模板,可以使用空模板参数列表:myPrint<>(a,b);
           2.如果函数模板能产生更好的匹配,优先使用函数模板
           
4.函数模板----------->模板函数:过程是由抽象到具体(实例化的过程),在实参进行传递的时候进行类型推导    

5.函数模板的全特化和偏特化----模板并不是真实通用,对于自定义的数据类型,需要进行特化来使用。
    1.模板的全特化:把模板的参数全部特殊化表示出来:template<>,用空模板参数来进行全特化
    2.把模板的参数进行一部分特殊化(C++11之后才支持的)
    
6.函数模板的参数类型:1.类型参数:class/typename T        
                   2.非类型参数:常量表达式,整型:bool/char/short/int/long/size_t。
                   3.参数类型可以可以设默认值
                   
7.类模板总结
    1.类模板的使用只能显式指定类型,可以有默认参数。
    2.类模板中的成员函数并不是一开始创建的,而是在运行阶段确定出T的数据类型的时候才去创建
    3.类模板做函数的参数:
            1.显式指定传入的类型void doWork(Person <string,int>&p)
            2.参数模板化:template <class T1,class T2>
                        void doWork2(Person <T1,T2>&p)
            3.整个类模板化:
                template <class T>
                void doWork3(T &p)
    4.类模板继承问题:派生类继承基类的时候,必须指定基类中T的类型,
    5.类中成员在类外实现的写法
    6.友元函数的类外实现.

8.C++11可变模板参数---重点难点
    1.class... Args或者typename... Args:模板参数包--->class T1, class T2....
    2.Args类型后面跟一个省略号:Args... args--->表示0个或者多函数参数,函数参数包
        ---》T1 t1, T2 t2.....
    3.可变参数函数通常是递归的,第一步调用处理包中的第一个实参,然后剩余实参调用自身,为了终止递归,需要定义一个非可变参数的print函数。用来终止递归。
    
9.实战演练:
        1.类模板实现Stack/循环队列Queue
        2.单例模式通用模板,可传递任意参数,注意嵌套类成员的初始化

1.可变模板参数例子test01()

1.省略号...位于函数参数args左边的时候,为打包,相当于T1 t1, T2 t2...

2.省略号...位于参数args右边,为拆包

void print()//终止递归的条件
{
    cout<<endl;
}
//在display中不能进行打印,把参数进行拆分来进行打印
template <typename T,typename... Args>//相当于class T1, class T2,......
void print(T t, Args... args)//省略号...位于参数左边的时候,为打包,相当于T1 t1, T2 t2....
{
    cout<<t<<" ";
    print(args...);//省略号...位于参数右边,为拆包
    //拆包递归进行打印
}
void test02()
{
    //print();
    print(1);
    print(1,2.2,true); 
    print(1,2.2,true,"hello world");
}

运行结果

1

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

给你。

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值