111 C++ typename

介绍typename之前,应先了解几个概念:

1. 限定名与非限定名

限定名,顾名思义,是限定了命名空间的名称。

#include <iostream>int main()  
{std::cout << "Hello world!" << std::endl;
}


std::限定了std这个命名空间,故称为限定名。

#include <iostream>
using namespace std;int main()  
{cout << "Hello world!" << endl;
}


使用了using namespace std,就不再需要std::限定,此时cout和endl叫做非限定名

2. 依赖名与非依赖名


依赖名是指依赖于模板参数的名称,

非依赖名指不依赖模板参数的名称。

template <class T>
class MyClass {int i;vector<int> vi;vector<int>::iterator vitr;T t;        //由于依赖于模板参数T,只有在模板实例化的时候才能知道他们的类型vector<T> vt;vector<T>::iterator viter;
};


T、vector<T>和vector<T>::iterator称为依赖名,

int、vector<int>和vector<int>::iterator称为非依赖名。

3. 类作用域


类外部访问类中的名称时,存在三种方式:

1)静态数据成员

2)静态成员函数

3)嵌套类型

struct MyClass {
    static int A;
    static int B();
    typedef int C;
}
可分别使用MyClass::A、MyClass::B和MyClass::C表示

4. 引入typename的原因


来看下面一个例子:

 

template<class T>
void foo()
{T::iterator * iter;
}

T::iterator 这样的一个定义可以是以上三种类作用域中的任意一种类型。
(1)如果iterator是嵌套类型将正确执行,这段代码的意思是定义一个 T::iterator类型的数据。
(2)当iterator是静态数据成员时,以上代码将被解释为两个数相乘,返回值抛弃。如果iter没有定义,将报错;但如果iter是全局变量,将执行。
在模板实例化之前完全没有办法区分,因此,有必要引入新的关键字typename来区分这两种情况。

5. typename


5.1 基本使用


c++标准中有这么一句话:

A name used in a template declaration or definition and that is dependent on a template-parameter is assumed not to name a type unless the applicable name lookup finds a type name or the name is qualified by the keyword typename.
对于用于模板定义的依赖于模板参数的名称,只有在实例化的参数中存在这个类型名,或者这个名称前使用了typename关键字来修饰,编译器才会将该名称当成是类型。除了以上这两种情况,绝不会被当成是类型。

上面的例子可以修改为:

 

template<typename T>void print2nd(const T& container){typename T::iterator* x;  //让编译器确定T::iterator是一个类型,不是一个变量,而不需要等到实例化时确定//...}


5.2 使用规则


以下情况禁止使用typename:

1)模板定义之外,即typename只能用于模板的定义中

2)非限定类型,比如前面介绍过的int,vector<int>之类

3)基类列表中,比如class Derived :public Base<T>::Nested不能在public Base<T>::Nested前面加typename

4)构造函数的初始化列表中

template<typename T>class Derived :public Base<T>::Nested //此处不可以使用typename{public:explicit Derived(int):Base<T>::Nested(x)//此处不可以使用typename{typename Base<T>::Nested temp; //此处可以使用typename}


 

5.3 traits中的使用


代码示例:

template<typename IterT>
 
void workWithIterator(IterT iter)
 
{
 
    typename std::iterator_traits<IterT>::value_type temp(*iter);
 
    //...
 
}
此处我们使用到了iterator_traits<>模板类,其实是一种traits类。我们传递给其一个迭代器类型为其进行实例化,那么我们就可以通过其value_type萃取出迭代器所指的容器的类型。例如:

        1)如果IterT是list<string>::iterator,那么value_type就代表string,temp的类型就是string

        2)如果IterT是vector<int>::iterator,那么value_type就代表int,temp的类型就是int

因为value_type也是一种内嵌类型,因此我们需要使用typename声明其是一种类型

如果上面的代码比较复杂,那么我们还可以搭配typedef来使用,typedef是声明一个类型的别名。

template<typename IterT>
 
void workWithIterator(IterT iter)
 
{
 
    typedef typename std::iterator_traits<IterT>::value_type value_type; //为类型声明别名
 
    value_type temp(*iter); //使用类型定义变量
 
    //...
 
}
stl源码中有很多类似的例子,例如:

typedef typename __type_traits<T>::has_trivial_destructor trivial_destructor;
它表示:将__type_traits<T>这个模板类中的has_trivial_destructor嵌套类型定义一个叫做trivial_destructor的别名

6 总结
Effective C++条款42:模板与泛型编程(了解typename的双重意义)中有如下总结:

1)声明template参数时,前缀关键字class和typename可互换

2)请使用关键字typename标识嵌套从属类型名称;但不得在base class lists(基类列)或member initialization list(成员初值列)内以它作为base class修饰符

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/687142.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

re-captioning技术是什么

参考https://zhuanlan.zhihu.com/p/664192860 模型对图片进行caption操作时&#xff0c;输出的标题一般描述图片中的主体&#xff0c;而忽视了背景、常识关系等更为细节的描述。 图片比较重要的细节的描述应当包括&#xff1a; 物体存在的场景。如&#xff1a;在厨房的水槽&am…

ValueError check_hostname requires server_hostname 报错

一、报错再现 我准备了一个工具环境&#xff0c;这里面有一些工具包需要安装&#xff0c;当我运行一下代码&#xff1a; pip install -r requirements-cpu.txt回车过后&#xff0c;发生了如下报错&#xff1a; ERROR: Exception: Traceback (most recent call last):File &q…

Qt之条件变量QWaitCondition详解(从使用到原理分析全)

QWaitCondition内部实现结构图&#xff1a; 相关系列文章 C之Pimpl惯用法 目录 1.简介 2.示例 2.1.全局配置 2.2.生产者Producer 2.3.消费者Consumer 2.4.测试例子 3.原理分析 3.1.辅助函数CreateEvent 3.2.辅助函数WaitForSingleObject 3.3.QWaitConditionEvent …

阿里云服务器服务费怎么计算的?详细报价解析

2024年最新阿里云服务器租用费用优惠价格表&#xff0c;轻量2核2G3M带宽轻量服务器一年61元&#xff0c;折合5元1个月&#xff0c;新老用户同享99元一年服务器&#xff0c;2核4G5M服务器ECS优惠价199元一年&#xff0c;2核4G4M轻量服务器165元一年&#xff0c;2核4G服务器30元3…

算法学习(六)前缀和

前缀和 1. 概念 前缀和算法是一种用于高效计算数组前缀和的算法。前缀和是指从数组的起始位置到某一位置的所有元素的和。下面是前缀和算法的基本步骤&#xff1a; 创建一个与原始数组相同长度的前缀和数组。初始时&#xff0c;前缀和数组的第一个元素与原始数组的第一个元素…

001 - Hugo, 创建一个网站

001 - Hugo, 创建一个网站安装hugoWindows系统Macos Hugo博客搭建初始化博客主题安装配置博客各个页面开始创作创建 GitHub Page 仓库本地调试和预览发布内容 教程及鸣谢文字教程视频教程 001 - Hugo, 创建一个网站 这篇文章假设你已经&#xff1a; 了解基本的终端命令行知识&…

LaTeX中的计数器counter

诸神缄默不语-个人CSDN博文目录 计数器在LaTeX文档中扮演着重要的角色&#xff0c;用于自动化管理章节编号、页码、图表编号等。 计数器可以理解为LaTeX中的一个变量&#xff0c;用于存储一个整数&#xff0c;LaTeX通过这些计数器来控制文档的各种编号。 文章目录 创建计数器设…

黑马鸿蒙教程学习1:Helloworld

今年打算粗略学习下鸿蒙开发&#xff0c;当作兴趣爱好&#xff0c;通过下华为那个鸿蒙开发认证&#xff0c; 发现黑马的课程不错&#xff0c;有视频和完整的代码和课件下载&#xff0c;装个devstudio就行了&#xff0c;建议32G内存。 今年的确是鸿蒙大爆发的一年呀&#xff0c;…

Win32汇编数组学习2

之前学习过win32汇编数组&#xff1b;还不熟悉&#xff1b;继续熟悉&#xff1b; 先做几个基本的对话框&#xff0c;有一个静态文本框&#xff1b; 定义数组之后&#xff0c;用 wsprintf 函数格式化&#xff0c;然后调用 SetDlgItemText 赋值给静态文本框&#xff1b; arr1 …

【力扣hot100】刷题笔记Day5

前言 回学校了&#xff0c;荒废了半天之后打算奋发图强猛猛刷题&#xff0c;找实习&#xff01;赚钱&#xff01;&#xff01; 560. 和为 K 的子数组 - 力扣&#xff08;LeetCode&#xff09; 前缀法 哈希表 这个题解解释比官方清晰&#xff0c;截个图方便看&#xff0c;另一…

OpenCV-42 直方图均匀化

目录 一、直方图均匀化原理 二、直方图均匀化在OpenCV中的运用 一、直方图均匀化原理 直方图均匀化是通过拉伸像素强度的分布范围&#xff0c;使得在0~255灰阶上的分布更加均匀&#xff0c;提高图像的对比度。达到改善图像主管视觉效果的目的。对比度较低的图像适合使用直方…

由于找不到MSVCP140.dll无法运行软件游戏,多种解决方法分享

电脑系统在运行过程中&#xff0c;当出现“由于找不到MSVCP140.dll”这一提示时&#xff0c;可能会引发一系列潜在的问题与影响。当电脑无法找到这个特定的dll文件时&#xff0c;意味着相关应用可能无法顺利加载并执行必要的组件&#xff0c;进而导致程序无法启动或运行过程中频…

【PCB】Allegro PCB 的模块复用操作

【PCB】Allegro PCB 的模块复用操作

openJudge | 循环移动 C语言

总时间限制: 1000ms 内存限制: 65536kB 描述 给定一组整数&#xff0c;要求利用数组把这组数保存起来&#xff0c;再利用指针实现对数组中的数循环移动。假定共有n个整数&#xff0c;则要使前面各数顺序向后移m个位置&#xff0c;并使最后m各数变为最前面的m各数。 注意&…

51_蓝桥杯_led流水灯

一 原理图分析 二 三八译码器工作原理 三八译码器&#xff1a;3个输入控制8路互斥的低电平有效输出。 C B A 输出 0 0 0 Y0 0 0 1 Y1 0 1 0 Y2 0 1 1 Y3 1 0 0 Y4 1 0 1 Y5 1 1 0 Y6 1 1 1 Y7 三 锁存器工作原理 锁存器&#xff1a;当使…

Open CASCADE学习|布尔运算

目录 1、加法&#xff1a;BRepAlgoAPI_Fuse 2、减法&#xff1a;BRepAlgoAPI_Cut 3、交集&#xff1a;BRepAlgoAPI_Common 4、交线&#xff1a;BRepAlgoAPI_Section 1、加法&#xff1a;BRepAlgoAPI_Fuse #include <gp_Pnt.hxx>#include <BRepPrimAPI_MakeBox.hxx…

“我觉得我今年可能要随便找个人嫁了,下半辈子应该都不会再快乐了”

2月15日&#xff0c;“张颂文情商”的话题登上热搜&#xff0c;引发网友热议。 许多人对张颂文老师的情商表达了高度的赞扬和敬意&#xff0c;纷纷感叹&#xff1a;“张颂文老师真的是一个非常会安慰人的人&#xff01;” 在2月13日的一条微博中&#xff0c;张颂文分享了家里三…

【JavaEE】_HTTP请求首行

目录 1. URL 2. 方法 2.1 GET方法 2.2 POST方法 2.3 GET与POST的区别 2.4 低频使用方法 1. URL 在mysql JDBC中已经提到过URL的相关概念&#xff1a; 如需查看有关JDBC更多内容&#xff0c;原文链接如下&#xff1a; 【MySQL】_JDBC编程-CSDN博客 URL用于描述某个资源…

K8s进阶之路-安装部署K8s

参考&#xff1a;&#xff08;部署过程参考的下面红色字体文档链接就可以&#xff0c;步骤很详细&#xff0c;重点部分在下面做了标注&#xff09; 安装部署K8S集群文档&#xff1a; 使用kubeadm方式搭建K8S集群 GitBook 本机&#xff1a; master&#xff1a;10.0.0.13 maste…

[项目管理] 办公室环境的问题

目前的现状是&#xff1a;由于MS-teams的应用&#xff0c;在家办公的普及&#xff0c;以及会议室的紧缺&#xff0c;导致很多会议是在线上进行&#xff1b;综合下来的最终结果是会议比较多&#xff0c;尤其是周一二&#xff0c;而且大都是线上进行。最要命的是现状开放式的办公…