• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >C语言 > C++的template模板中class与typename关键字的区别分析

C++的template模板中class与typename关键字的区别分析

作者:visayafan 字体:[增加 减小] 来源:互联网 时间:2017-05-28

visayafan 通过本文主要向大家介绍了template typename t,template typename,template typename tp,template typename e,c++ typename等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

在C++模板中,可以使用class或者typename来声明模板参数,那么这两个关键字有什么区别呢?

模板参数声明
对于模板参数声明,这两个参数没有区别,含义是一样的。

template class Simple;
template class Simple;
</div>

上面两行都是声明一个模板类Simple.

表明类型
假如我们有这样一段代码:

template


void add(const T &acontainer, T &sum)
{
  T::const_iterator iter = container.begin();
  for (; iter != container.end(); ++iter) {
    sum += *iter;
  }
}

</div>

iter的类型是T::const_iterator,这个类型依赖模板参数T。把依赖模板参数的名称称为依赖名称。当这个依赖名称又在一个类中时,称为嵌套依赖名称。相对的,称为非嵌套依赖名称。

嵌套依赖名称会导致编译器编译的困难,例如下面的代码:

template


void add(const T &container)
{
  T::const_iterator *x;
  ...
}

</div>

这看起来像声明一个变量x,它的类型为T::const_iterator *。但是编译器并不知道,也有可能类T中又一个static数据成员const_iterator,或者正好有一个全局变量x。这时上面的代码就变成乘法操作。这是因为 C++编译器在处理模板的时候,会将需要推导的数据类型暂时搁置,到运行时再确定。

当编译器遇到一个模板中的嵌套依赖名称时,编译器将它作为变量对待。因此,需要显示的告诉编译器,这就需要使用关键字typename。

template
void add(const T &container, T &sum)
{
  typename T::const_iterator iter = container.begin();
  for (; iter != container.end(); ++iter) {
    sum += *iter;
  }
}
</div>

因此,使用嵌套依赖的类型名称时,都需要使用typename指定它是一种类型。

例外
嵌套依赖名称在基类列表中,或者在成员初始化列表中时,不能使用typename。

template
class Drived: public Base::Nested { // 基类列表,不要使用typename
public:
  explicit Derived(int x): Base::Nested(x) { // 成员初始化列表,不要使用typename
    typename Base::Nested temp;
    ...
  }
  ...
};

</div>

另外一些注意点

1、嵌套从属名称(nested dependent names)
假如template内出现的名称如果依赖于某个模板参数,则称其为从属名称(dependent names),如果从属名称在class内呈嵌套状则称之为嵌套从属名称(nested dependent names)。
例如:

templaet <typename T>void myPrint(const T& t){
  t::const_iterator iter(t.begin());
}
</div>

假设模板参数列表中的参数表示一个容器类型,则我们知道t::const_iterator一个依赖模板参数并且在容器内部,所以t::const_iterator是一个嵌套从属名称。

在我们知道t是什么之前没有办法可以知道t::const_iterator是否是一个类型,因为有还可能是个静态(static)成员变量,考虑下面的例子:

template <typename T>void myPrint(const T& t){
  t::const_iterator * x;
}
</div>

如果const_iterator是t的静态成员变量,则上面的t::const_iterator * x;中的*表示乘法,如果是个类型则表示声明一个指向t::const_iterator类型的指针。
从而给编译器造成困惑(因为我们不知道t是什么)。

C++有个规定:当解析器在模板中遇到一个嵌套从属名称时便假定这个名称不是类型,除非你用关键字typename指定它是:

template <typename T>void myPrint(const T& t){
  typename t::const_iterator * x;   //这样便不会造成困惑了}
</div>

同理不仅在内部,在参数列表里也是:

template <typename T>void f(const T& t, typename T::const_iterator cit){
   //T不是嵌套从属名称,而T::const_iterator是,所以要在T::const_iterator前面加上typename    //....}

</div> 基类列表(base list)和成员初始化列表(member initializaiton list)
 
</div>
template <typename T>class Derived: public Base<T>::Nested {         //基类列表中不允许使用typenamepublic:
  explicit Derived(int x): Base<T>::Nested(int x){  //初始化列表中不允许使用typename    typename Base<T>::Nested temp;         //嵌套从属名称(既不在基类列表中又不在初始化列表中)前面必须要加typename  }
}
</div> </div>
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • C++的template模板中class与typename关键字的区别分析
  • 详解C++的模板中typename关键字的用法
  • c++中typename和class的区别介绍

相关文章

  • 2017-05-28C语言 扫雷程序的实现
  • 2017-05-28C语言单链表的实现
  • 2017-05-28C++中vector和map的删除方法(推荐)
  • 2017-05-28C++封装IATHOOK类实例
  • 2017-05-28深入理解void以及void指针的含义
  • 2017-05-28C语言学生管理系统源码分享
  • 2017-05-28最大子矩阵问题实例解析
  • 2017-05-28C语言putenv()函数和getenv()函数的使用详解
  • 2022-04-30在C语言中使用英文字符
  • 2017-05-28C++空类默认函数详细解析

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • C语言中的数组和指针汇编代码分析实例
    • C++中对象的常引用总结
    • C++指向函数的指针实例解析
    • socket多人聊天程序C语言版(二)
    • 头文件不宜定义变量的原因全面解析
    • C++中extern "C"的用法
    • 最大子矩阵问题实例解析
    • 关于C++使用指针 堆和栈的区别分析
    • c语言多进程tcp服务器示例
    • C语言中的二进制数、八进制数和十六进制数

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有