C++typename的由来和用法

作者: 良知犹存

前言

在C++模板函数的使用过程中,们经常可以看到一个typename的使用,例如这样的操作

但是除此之外,们也会经常看到这样的用法

那么这里就要问大家,这C++类似的用法下有什么区别呢,且听细细道来。


作者:良知犹存

转载授权以及围观:欢迎添加微信公众号:羽林君


由来分析

“typename"是一个C++程序设计语言中的关键字。当用于泛型编程时是另一术语"class"的同义词。这个关键字用于指出模板声明(或定义)中的非独立名称(dependent names)是类型名,而非变量名。

们经常会这么用 typename,这是一项C++编程语言的泛型编程(或曰"模板编程”)的功能,typename关键字用于引入一个模板参数。

template <typename T> const T& max(const T& x, const T& y) { if (y < x) { return x; } return y; } 

在模板定义语法中关键字 class 与 typename 的作用完全一样

template<class T> const T& max(const T& x, const T& y) { if (y < x) { return x; } return y; } 

这里 class 关键字表明T是一个类型,后来为了避免 class 在这两个地方的使用可能给人带来混淆,所以引入了 typename 这个关键字,它的作用同 class一样表明后面的符号为一个类型。

那class使用就够了,为什么又引入了新的关键词 typename ,关于这个问题,Stan Lippman 曾在其中表示,最早 Stroustrup 使用 class 来声明模板参数列表中的类型是为了避免增加不必要的关键字;后来委员会认为这样混用可能造成概念上的混淆才加上了 typename 关键字。

而使用 typename 的作用就是告诉 c++ 编译器,typename 后面的字符串为一个类型名称,而不是成员函数或者成员变量,这个时候如果前面没有 typename,编译器没有任何办法知道 T::LengthType 是一个类型还是一个成员名称(静态数据成员或者静态函数),所以编译不能够通过。

问题浮现

那么问题来了,什么情况下,class定义之后,编译不能通过呢?

template<typename T>
void fun(const T& proto){


        T::const_iterator it(proto.begin());
}

发生编译错误是因为编译器不知道T::const_iterator是个类型。万一它是个变量呢? T::const_iterator的解析有着逻辑上的矛盾: 直到确定了T是什么东西,编译器才会知道T::const_iterator是不是一个类型; 然而当模板被解析时,T还是不确定的。这时们声明它为一个类型才能通过编译:

而且在模板实例化之前,完全没有办法来区分它们,这绝对是滋生各种bug的温床。这时C++标准委员会再也忍不住了,与其到实例化时才能知道到底选择哪种方式来解释以上代码,委员会决定引入一个新的关键字,这就是typename

千呼万唤始出来,们来看看C++标准:

对于用于模板定义的依赖于模板参数的名称,只有在实例化的参数中存在这个类型名,或者这个名称前使用了typename 关键字来修饰,编译器才会将该名称当成是类型。除了以上这两种情况,绝不会被当成是类型。

因此,如果你想直接告诉编译器 T::const_iterator 是类型而不是变量,只需用 typename修饰:

typename    T::const_iterator it(proto.begin());

这样编译器就可以确定T::const_iterator是一个类型,而不再需要等到实例化时期才能确定,因此消除了前面提到的歧义。

嵌套从属类型

事实上类型T::const_iterator依赖于模板参数T, 模板中依赖于模板参数的名称称为从属名称 (dependent name), 当一个从属名称嵌套在一个类里面时,称为嵌套从属名称 (nested dependent name)。 其实T::const_iterator还是一个嵌套从属类型名称(nested dependent type name)。

嵌套从属名称是需要用typename声明的,其他的名称是不可以用typename声明的。比如下面是一个合法的声明:

template<typename T> void fun(const T& proto ,typename  T::const_iterator it); 

使用

在定义类模板或者函数模板时,typenameclass 关键字都可以用于指定模板参数中的类型。也就是说,以下两种用法是完全等价的。

template<typename T> /* ... */; template<class T> /* ... */; 

既然typename关键字已经存在,而且它也可以用于最常见的指定模板参数,那么为什么不废除class这一用法呢?答案其实也很明显,因为在最终的标准出来之前,所有已存在的书、文章、教学、代码中都是使用的是class,可以想像,如果标准不再支持class,会出现什么情况。

使用关键字typename代替关键字class指定模板类型形参更为直观,毕竟,可以使用内置类型(非类类型)作为实际的类型形参,而且,typename更清楚地指明后面的名字是一个类型名。但是,关键字typename是作为标准C++的组成部分加入到C++中的,因此旧的程序更有可能只用关键字class

这就是分享的c++的typename,此外如果大家有什么更好的思路,也欢迎分享交流哈。

END—**

推荐阅读

【1】linux开发各种I/O操作简析,以及select、poll、epoll机制的对比

【2】嵌入式底层开发的软件框架简述

【3】CPU中的程序是怎么运行起来的 必读
【4】什么?还不懂c++vector的用法,你凭什么勇气来的!
【5】阶段性文章总结分析

本公众号全部原创干货已整理成一个目录,回复[ 资源 ]即可获得。

参考链接:

https://liam.page/2018/03/16/keywords-typename-and-class-in-Cxx/

https://harttle.land/2015/09/09/effective-cpp-42.html

http://feihu.me/blog/2014/the-origin-and-usage-of-typename/

更多分享,扫码关注

原文作者:良知犹存

原文链接:https://www.cnblogs.com/conscience-remain/p/14110702.html

更多推荐

更多
  • 面试AI技术内参-031经典搜索核心算法:TF 031 经典搜索核心算法:TF-IDF及其变种先来介绍TF-IDF算法。 在信息检索(Information Retrieval)、文本挖掘(Text Mining)以及自然语言处理(Natural Language Processi
  • 面试AI技术内参-004精读2017年EMNLP最佳长论文之一 004 精读2017年EMNLP最佳长论文之一irical Methods in Natural Language Processing),是由国际计算语言学协会**ACL** (Association for Computationa
  • 面试AI技术内参-126复盘5计算机视觉核心技术模块 126复盘 5 计算机视觉核心技术模块 复盘 5 计算机视觉核心技术模块 今模块里,我们一起学习了12期内容,讨论了四个话题,这些话题主要围绕计算机视觉的基础知识和深度学习技术在这个领域的应用。 之所以这么安排,是因为没有深度学
  • 面试AI技术内参-037查询关键字理解三部曲之分类 037 查询关键字理解三部曲之分类技术和基于机器学习的排序算法(Learning to Rank)。 经典的信息检索技术为2000年之前的搜索引擎提供了基本的算法支持。从中衍生出的TF-IDF、BM25还有语言模型(Language
  • 面试AI技术内参-019SIGIR2018论文精读:偏差和流行度之间的关系 019 SIGIR 2018论文精读:偏差和流行度之间的关系2日在美国密歇根州的安娜堡举行。从今天开始,我将精选几篇大会上最有价值的论文,和你一起来读。 我先简单介绍一下这个大会。SIGIR从1978年开始举办,有40年的历史,是信息
  • 面试AI技术内参-022CVPR2018论文精读:如何研究计算机视觉任务之间的关系? 022 CVPR 2018论文精读:如何研究计算机视觉任务之间的关系?PR(Conference on Computer Vision and Pattern Recognition),在美国的盐湖城举行。CVPR大会从1985年开始举
  • 面试AI技术内参-021SIGIR2018论文精读:如何对搜索页面上的点击行为进行序列建模? 021 SIGIR 2018论文精读:如何对搜索页面上的点击行为进行序列建模? 我们已经分享了SIGIR 2018的最佳论文,介绍了如何对推荐系统中的偏差进行建模,从而能够利用这种对偏差的理解,来更加准确地对待基于流行度的推荐结果。周
  • 面试AI技术内参-024CVPR2018论文精读:如何解决排序学习计算复杂度高这个问题? 024 CVPR 2018论文精读:如何解决排序学习计算复杂度高这个问题?于排序的损失函数的有效优化》(Efficient Optimization for Rank-based Loss Functions)。 还是先简单介绍下论文
  • 面试AI技术内参-061基于隐变量的模型之一:矩阵分解 061 基于隐变量的模型之一:矩阵分解 -内容特征的推荐模型。 这周,我们来看一类非常重要的推荐模型:**基于隐变量的推荐模型**。这类模型的优势是对用户和物品信息中的隐含结构进行建模,从而能够挖掘更加深层次的用户和物品关系。 什么
  • 面试AI技术内参-107基于门机制的RNN架构:LSTM与GRU 107 基于门机制的RNN架构:LSTM与GRU -地利用了文字的序列信息,从而能够对文本进行大规模的建模。在上一次的分享里,我们聊了对序列建模的深度学习利器"递归神经网络",或简称RNN。我们分析了文本信息中的序列数据,了解了如何对文
  • 近期文章

    更多
    文章目录

      推荐作者

      更多