您好,欢迎来到乌哈旅游。
搜索
您的当前位置:首页条款42:了解typename的双重意义

条款42:了解typename的双重意义

来源:乌哈旅游

 条款42:了解typename的双重意义
 Understand the two meanings of typename.

内容:
     看下面template声明式中,class与typename有什么不同?
     template<class T> class Widget;//use "class "
     template<typename T> class Widget;//use "typename"
     某些程序员喜欢用class,因为可以少打几个字母.还有一部分开发人员喜欢在接受任何类型时使用typename,而在接受用户自定义类型时保留旧式的class.然而实际上,从C++角度来看,声明template参数时,不论使用关键字class或typename意义完全相同.但这并不等于说C++总是 把class和typename视为等价.有时候你一定得使用typename.
     看下面这个无聊的template函数,以无聊的方式实现,甚至连编译都通不过,但我们先忽略这些事实,我们来看它的实现体:
     tempalte <typename C>
     void print2nd(const C& container)//打印容器内的第二元素
     {
         if( containter.size() >= 2 ){
             C::const_iterator iter( containter.begin() );
             ++iter;
             int value = *iter;
             std::cout << value;
         }
     }
     对于这里的C::const_iterator而言,我们现在无法知道其是否为一个类型,除非你告诉我C是什么.那编译器开始解析template print2nd时,它将如何解析它呢?C++的解析此歧义状态的规则是:如果在template中遭遇一个嵌套从属名称,它遍假设这名称不是个类型,除非你告诉它是.所以在缺省情况下嵌套从属名称不是类型.如果你告诉它你是类型的话,你不得不在其前面加上typename进行修饰.即:
     template <typename C>
     void print2nd(const C& containter)
     {
         if( container.size() >= 2 ){
             typename C::const_iterator iter( container.begin() );
             ...
         }
     }
     一般规则很简单:任何时候你想要在template中指定一个嵌套从属类型名称,就必须在紧临它的前一个位置放上关键字typename.好,下面我们来看一个例外,这一规则的例外是,typename不可以出现在base classes list内的嵌套从属类型名称之前,也不可在member initailization list(成员初值列)中作为base class修饰符.例如:
     template <typename T>
     class Derived:public Base<T>::Nested{ //base class list中不允许出现"typename"
     public:
         explicit Dervied(int x) 
         : Base<T>::Nested(x){ //成员初始化列表中不允许"typename"
              typename Base<T>::Nested temp; //既不在base class list也不在初始化列表中,作为一个base class修饰符需加上typename.
             ...
         }
         ...
     };
     在本款快结束的时候,我们要注意这样的一个问题:typename相关规则在不同的编译器上有不同的实践.某些编译器接受的代码原本该有typename却遗漏了;原本不该有typename却出现了;还有少数编译器(通常是较旧版本)根本就拒绝typename.这意味typename和"嵌套从属类型名称"之间的互动,也许会在移植性方面带给你某种温和的头疼.
     请记住:
     ■ 声明template参数时,前缀关键字class与typename可互换.
     ■ 请使用关键字typename标识嵌套从属类型名称;但不得在base class lists(基类列)或member initailization list(成员初值表列)内以作为base class修饰符.

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- wuhaninfo.cn 版权所有

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务