C++Template 读书笔记 第五章

内容:技巧性基础知识

关键字:typename     .template    this->     模板的模板参数       零初始化        字符串的模板实参

具体内容描述

       1.  对模板使用typename

                  场景:

                           template <typename T>

                            class Test{

                                       typename T::SubType *ptr;     //使用模板参数类型里面定义的类型

                                       ...............

}

                         这里需要增加typename,需要标记告诉编译器这个是声明一个模板参数类型T里面的SubType类型的指针,指明T::SubType是一个类型

                         如果不指定typename,编译器认为是T里面的一个静态成员

      2.   使用模板参数时附带.tmpelate关键字

                 场景

                       template <tint N>

                       void printBitset (std::bitset<N> const &bs)

                       {

                             std::cout<<bs.template to_string<char, char_traits<char>,allocator<char> > ();    //这里在bs后面增加.template

                      }

                     这里和上面typename类似也是告诉编译器这里要对to_string模板函数进行处理,to_string后面紧跟的<不是小于符号是模板参数列表的开始标示

                     我们可以做一个比较,bs里面的to_string函数分为普通函数和模板函数来对比

                            bs.to_string()

                            bs.to_string<char>()

                            在使用to_string函数时不告诉编译器这个to_string函数是一个模板函数,那么紧跟函数后面的<将被认为是小于符号

                     扩展:可以扩展到使用一个模板参数T里面的一个模板函数需要增加::template,是一个指针时需要增加->template

      3.    在模板类中使用this->

              场景

                    template<typename T>

                    class Base{

                            void exit(){};

                   '}

                     template<typename T>

                    class Test : public Base<T>{

                           vodi print(){

                                 exit();     //调用全局的exit函数,如果没有全局的将编译错误

                                 this->exit();    //调用基类中的exit函数

                           }

                    }

             在模板类中如果基础的基类也是一个模板类,在继承类中使用基类定义的函数需要显示指定this->也可以用名字空间标示Base<T>::exit()

     4.   模板的模板参数

              模板的模板参数就是将模板本身作为另一个模板的参数

              典型的使用场景

                    在STL容器中的类型,容器可以变,容器中的参数也可以变(这里只给出声明和使用)

                    template <typename T, typename CONT=std::vector>

                    class Stack{.........}

                    使用Stack<int > Test;  使用默认容器。

                     如果换容器会是怎样?

                              Stack<int, std::deque<int> > Test 这里需要显示的指明

                    那就定义一个模板的模板参数来去掉这个显示的指明

                   template<typename T, template <typename ELEM> class CONT=std::vector>

                   class Stack{CONT<T> val;   ........}

                   使用Stack<int, std::deque> Test,这里会完成自动推演出来-------------函数模板没有模板的模板参数这回事!!!!!!!!

                    注意:i    模板的模板参数中如果ELEM没有被使用可以不用显示写出来

                               ii    模板的模板参数需要精确的实参匹配,所以最新的Stack的声明为

                                    template <typename T, template <typename ELEM, typename ALLOC=std::allocator> >class CONT=std::vector>

                                    class Stack{.....}

5 零初始化

           零初始化时指声明的一个命令都能够被正确初始化,比如一个内置类型int,这声明后的指是不确定的必须要显性的初始化赋值才行。

           这个问题的模板中可以得到解决,看下面的例子

           template<typename T>

            vod fun(){

                  T x = T();   //这里可以做到声明和初始化一次解决,这个主要是针对内置类型而言

            };


6  字符串作为函数模板的实参

             我们在声明一个函数时对函数的参数会有值的传递或引用的传递(考虑到演示就不说指针的方式)

             template<typename T>

            T max(T a, T b)   //版本一,传值方式

            T const& max(T const&a, T const &b);  //版本二,引用方式

            {return a< b > b:a;};   //这里是函数实体


           max("111","222");  //两个版本都没问题

           max("1111","222"); //版本二编译不通过---------这里的参数和上面的不同只有参数的长度不同,问题也就是出在字符串参数的长度上

           模板的引用方式,对字符串演绎为字符数组,长度为3和长度为4的数组对模板来说是不同类型---称为decay,而值引用都是指针char *

            针对这个问题给出的建议:

                1.使用非引用函数模板,但可能会导致无用拷贝

                2. 重载引用版本和非引用版本,可能会参数二义性 

                3. 重载数组类型

                        template <typename T, int N, int M>

                        T const * mac(T const(&a)[N], T const(&b)[M])

               4. 对具体类型进行重载,或者要求使用显示类型转换处理

          

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值