当前位置: 首页 > news >正文

const迭代器与模板构造函数

在自己实现C++中list的时候,当实现const迭代器的时候,发现报错了,一直思考到现在
才发现是一个,很简单的问题,但是也让我有了一点感受,我在这里给大家分享一下。

文章目录

  • 1.当时遇到的问题
  • 2.解决方法
  • 3. 自己的感悟

1.当时遇到的问题

这是list的构造函数部分
在这里插入图片描述
这是list迭代器调用的部分。
在这里插入图片描述
当我运行这样一段代码的时候,会出现这样的错误:
在这里插入图片描述
看得更清楚一点:
在这里插入图片描述
而这么写的时候是没问题的:

void Print(const zsw::list<int>& ls)
{zsw::list<int>::const_iterator cit = ls.begin();while (cit != ls.end()){cout << *cit << endl;cit++;}
}int main()
{zsw::list<int> ls;ls.push_back(1);ls.push_back(2);ls.push_back(3);ls.push_back(4);Print(ls);//zsw::list<int>::const_iterator cit = ls.begin();//while (cit != ls.end())//{//	cout << *cit << endl;//	cit++;//}return 0;
}

在这里插入图片描述

我当时想不通,为什么会出现这样的问题。
我一直以为这个问题是出现在begin函数上,因为我当时想的是,我左边是const迭代器对象,begin函数有两个一个是普通版本,一个是const版本,我一直认为右边的begin函数的返回值是:
在这里插入图片描述
这里就出现了第一个错误,不理解函数重载的功能,调用重载函数,区别应该是体现在调用对象和传的参数上来体现。这里的ls是普通对象,所以调用的应该是普通版本的begin函数。
既然是调用的普通begin函数返回的就是普通迭代器,这就是问题的所在,我begin函数返回的的对象类型是Iterator<int, int& int*>,而对象cit的类型是Iterator<int, const int& const int*>,两者是不同的类型,而在cit的模板类实例化之后,cit是没有关于Iterator<int, int& int*>类型的构造函数的:
在这里插入图片描述

2.解决方法

它这里的构造函数只有用节点或者同类型的迭代器来初始化。
所以我们只需要添加这样的一个构造函数。
在这里插入图片描述
可以看到它是一个模板函数,这样就可以通过Iterator<int, int& int*>类型来构造Iterator<int, const int& const int*>,而这其中T1和T应该具有相似特性,为了传参正确,更严谨的写法:
在这里插入图片描述
上面的解决方法我是从STL中map的一个返回值理解的:
在这里插入图片描述

我们看到map的插入函数的参数是这样的一个,我们来看看它是什么:
在这里插入图片描述
其实它是一个结构体:

在这里插入图片描述
假如我们现在使用以下map:
在这里插入图片描述
它的编译的没有错误的,这显然与我们上面遇到的问题一样,map的插入函数需要的对象是pair<const key_type,mapped_type>,而对应到这里那它所需要的参数类型是pair<const string,string>,我们传的类型是pair<string, string>这又是两个不一样的类型。那么很显然解决方法就也是从这里来的:
在这里插入图片描述
在pair里就有这么一个模板构造函数。
可以看出这种构造函数又能充当拷贝构造又能充当构造

3. 自己的感悟

我们在上面看到一个pair<string, string>传参给pair<const string,string>的引用,好像跟这里有点相似:
在这里插入图片描述
可以看到它可以编译通过。那看这个,这不就是单个内置类型的成员变量的自定义类型之间的隐式类型转换嘛,要知道内置类型在C++中也是有“构造函数”的。
再看一段代码:

template<class T1, class T2>
class A
{
public:A(){}template<class N1, class N2>A(const A<N1, N2>& a):_a(a._a), _b(a._b){}T1 _a;T2 _b;
};void func(const A<double, double>& a)
{cout << "void func(A<const string, string> a)" << endl;
}int main()
{A<int, int> a1;func(a1);return 0;
}

在这里插入图片描述
也是能编译通过的。
在这里插入图片描述
那这里能够实现的原因还是因为,有着隐式类型转化的作用。而隐式类型转化又有着更底层的内置类型转换(比如double转int)的构造逻辑,或者是自定义类型本身就有相关类型的构造函数(例如const char*转string)这种转化是基于两种类型具有相似的特性,所以隐式类型转换和不同类型间的构造函数是相辅相成的。
这就是基于list的const迭代器得出的一点感悟,要是错了的话,希望能够改正我。

http://www.lryc.cn/news/215867.html

相关文章:

  • 在Qt中解决opencv的putText函数无法绘制中文的一种解决方法
  • 【Linux】第六站:Centos系统如何安装软件?
  • Istio 实战
  • 【Midjourney入门教程4】与AI对话,写好prompt的必会方法
  • 基于单片机的智能灭火小车设计
  • [Machine Learning][Part 7]神经网络的基本组成结构
  • 精准测试:提高软件质量和用户满意度的利器
  • 代碼隨想錄算法訓練營|第五十八天|583. 两个字符串的删除操作、72. 编辑距离、编辑距离总结篇。刷题心得(c++)
  • JavaScript基础之BOM与DOM
  • 【Linux学习笔记】进程概念(中)
  • scanpy赋值问题
  • 腾讯云域名备案后,如何解析到华为云服务器Linux宝塔面板
  • odoo 按钮打印pdf报表
  • 用逻辑分析仪观察串口Uart数据波形
  • 数据结构-栈应用括号匹配
  • leetcode做题笔记209. 长度最小的子数组
  • 【机器学习】几种常用的机器学习调参方法
  • 使用免费 FlaskAPI 部署 YOLOv8
  • 不使用屏幕在树莓派4B安装Ubuntu22.04桌面版(64位)
  • Pymysql模块使用操作
  • 8+双疾病+WGCNA+多机器学习筛选疾病的共同靶点并验证表达
  • springboot如何获取前端请求头的值并加入ThreadLocal
  • 程序员想要网上接单却看花了眼?那这几个平台你可得收藏好了!
  • 前端食堂技术周刊第 102 期:Next.js 14、Yarn 4.0、State of HTML、SEO 从 0 到 1
  • GPT与人类共生:解析AI助手的兴起
  • HTML脚本、字符实体、URL
  • UOS安装Jenkins
  • 纯CSS实现卡片上绘制透明圆孔
  • 用前端框架Bootstrap的AdminLTE模板和Django实现后台首页的页面
  • Linux驱动 编译乱序和执行乱序