首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

如何在自定义列表迭代器类中将迭代器转换为const_iterator?

在C++中,如果你想在自定义的列表迭代器类中将迭代器转换为const_iterator,你需要确保const_iterator能够访问但不能修改底层数据。以下是一个简单的例子,展示了如何实现这样的转换:

代码语言:txt
复制
#include <iostream>
#include <vector>

template <typename T>
class MyList {
public:
    class Iterator {
    protected:
        typename std::vector<T>::iterator it;
    public:
        Iterator(typename std::vector<T>::iterator iterator) : it(iterator) {}

        T& operator*() { return *it; }
        T* operator->() { return &(*it); }
        Iterator& operator++() { ++it; return *this; }
        bool operator!=(const Iterator& other) const { return it != other.it; }
    };

    class ConstIterator {
    protected:
        typename std::vector<T>::const_iterator it;
    public:
        ConstIterator(typename std::vector<T>::const_iterator iterator) : it(iterator) {}
        ConstIterator(const Iterator& iterator) : it(iterator.it) {} // 允许从Iterator转换为ConstIterator

        const T& operator*() const { return *it; }
        const T* operator->() const { return &(*it); }
        ConstIterator& operator++() { ++it; return *this; }
        bool operator!=(const ConstIterator& other) const { return it != other.it; }
    };

    MyList(std::initializer_list<T> init) : data(init) {}

    Iterator begin() { return Iterator(data.begin()); }
    Iterator end() { return Iterator(data.end()); }

    ConstIterator begin() const { return ConstIterator(data.begin()); }
    ConstIterator end() const { return ConstIterator(data.end()); }

private:
    std::vector<T> data;
};

int main() {
    MyList<int> list = {1, 2, 3, 4, 5};

    // 使用普通迭代器
    for (MyList<int>::Iterator it = list.begin(); it != list.end(); ++it) {
        std::cout << *it << ' ';
    }
    std::cout << '\n';

    // 使用const_iterator
    for (MyList<int>::ConstIterator it = list.begin(); it != list.end(); ++it) {
        std::cout << *it << ' ';
    }
    std::cout << '\n';

    // 将普通迭代器转换为const_iterator
    MyList<int>::ConstIterator const_it = MyList<int>::ConstIterator(list.begin());
    std::cout << *const_it << '\n';

    return 0;
}

在这个例子中,MyList类有两个嵌套的迭代器类:IteratorConstIteratorIterator可以修改元素,而ConstIterator只能读取元素。ConstIterator类有一个构造函数,它接受一个Iterator对象并将其转换为ConstIterator。这样,你可以安全地将非const迭代器转换为const迭代器,而不需要担心意外修改数据。

这种设计允许你在需要时灵活地使用不同类型的迭代器,并且可以很容易地在它们之间转换。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

C++ STL学习之【反向迭代器】

与正向相反就是反向,比如时钟正常都是顺时针转,但如果时钟逆时针选择,此时就称为反方向的钟 存在 vector() = {1, 2, 3, 4, 5} 不同方向的遍历结果不同 正向迭代器:正向遍历...,为了解决普通对象与 const 对象的代码冗余问题,引入了多参数,通过对形参传递不同的对象,变换为不同属性的迭代器;在反向迭代器类中,这一种巧妙思想也得到了继承 template<class Iterator..._cur); } 以上就是反向迭代器所必须的基础功能,如果你还想实现更多比较逻辑,如 operator<() 等,可以自己实现 反向迭代器类的完整代码: #pragma once namespace...,也是++ } cout << endl; } 此时主要是用到了 operator->() 访问自定义类型中的成员变量 ---- 4、源码 关于 vector 和 list (迭代器版)的源码在下面仓库中...vector(反向迭代器版) list(反向迭代器版) ---- 总结 以上就是本篇关于 C++ STL 学习之【反向迭代器】的全部内容了,在本篇文章中,我们主要学习了反向迭代器类的思想及实现,最后分别用了

15920
  • C++奇迹之旅:双向链表容器list的灵活使用技巧

    比如,在某些模板类中,编译器可能会自动用分配器创建 std::list。添加 explicit 关键字防止了这种隐式转换,确保只有当明确调用构造函数时才会使用该构造函数。...在 std::list 中: 插入操作:在 list 中插入元素不会导致其他迭代器失效。也就是说,插入新元素后,已有的迭代器仍然有效。...删除操作:当你删除某个元素时,与该元素关联的迭代器会失效,而其他的迭代器不会受到影响。...成员函数模板: template void merge(list& other, Compare comp); 说明: 使用自定义比较函数comp将other列表合并到当前列表中...在对std::list进行插入和删除操作时,需要注意迭代器可能会失效的问题,应该及时更新迭代器或使用安全的方式操作。

    9010

    C++效率掌握之STL库:list底层剖析及迭代器万字详解

    例如,在实现一个任务调度系统时,任务可能会随时被添加或移除,如果使用 std::list 来存储任务,就可以高效地处理这些操作 为了与库里的 list 进行区分,所有的类和函数都放在自定义的命名空间 bit...,所以当没有参数传入时就调用各自类型的默认构造函数进行传参 3.迭代器模版及实现 迭代器就是一个桥梁,让容器能通过迭代器实现算法 容器 迭代器 算法 根据迭代器的容器底层结构决定的性质...,可以大致分为三类: 单向迭代器(forward iterator):支持运算符重载 ++,常用容器为 forward_list、unordered_map、unordered_set 双向迭代器(bidirectional...cout << endl; for (auto e : lt) { cout << e << " "; } cout << endl; } 剖析底层代码先从功能入手,通常我们实现迭代器如代码所示...当自定义容器的 begin() 函数返回迭代器时,这些通用算法可以直接应用到自定义容器上,实现代码的复用 iterator 是 _list_iterator 模版的重命名,更符合使用习惯 begin

    12110

    【C++】list迭代器的深度剖析及模拟实现(感受类封装,类和对象的思想)

    list的迭代器我们用的是类模板定义出来的,也就是自定义类型的迭代器。vector的迭代器我们用的是原生指针定义出来的,也就是内置类型的迭代器。...// //下面的范围for会傻瓜式的替换为const迭代器 // for (auto& e : lt)//如果T是自定义类型,则会调用该类的拷贝构造,代价会很大,为了提高效率,这里用引用。...实现const迭代器的一种方式就是重新构建一个类,类里面原有成员函数都不变,仅仅是将类名做出修改,然后我们把解引用函数的返回值修改成常引用,在使用const_iterator迭代器类型的时候,如果你解引用迭代器则直接调用...五、反思迭代器类的设计,回顾类和对象的知识 1. 如果没有写析构函数,则编译器默认生成的析构函数对内置类型不会处理,对自定义类型会调用他的析构函数。...在栈实现队列那道题中,如果我们自己写了无参的默认构造,则成员变量也会在初始化列表进行初始化,在初始化列表处,对于自定义类型,初始化列表会调用他的默认构造。如果此时自定义类型没有默认构造,则会报错。

    1.1K10

    模拟实现c++中的vector模版

    3·vector增删查改: 如:push_back;pop_back;find(这时algorithm算法库内的函数,也是使用迭代器区间:找到了返回指向那个位置的迭代器,否则返回右区间);insert;...这里的iterator是迭代器类型可以粗略认为是指针,假设模版参数是T,故typedef一下: typedef T* iterator; typedef const T* const_iterator...()const { return _start; } const_iterator cend() const { return _finish; } 分别对可以修改和不允许修改的对象都有了对应的迭代器...对于缺省参数:如果未给值就会掉此类型默认构造(T()为匿名对象),对于内置类型如:char,int等这就是'\0',0。如果是自定义类型:就是它的默认构造函数构造出的对象。...:方便了不同类型 的迭代器区间去放入这个容器,如list: 12.vector以及容器通用打印的实现: //vector专属的打印: template void Print(const

    3600

    移情别恋c++ ദ്ദി˶ー̀֊ー́ ) ——7.list(模拟实现)

    1.前言 1.1list与vector的不同 区别:list的迭代器底层和其他两个迭代器底层有很大区别,因为list的链式结构决定了与它们两个的不一样 相同:迭代器用法大致一样,其他成员函数的使用也大致一样...,也就是哨兵位头节点的指针 4.list迭代器 4.1 list迭代器框架 这里的迭代器是用封装加运算符重载来实现的,由于迭代器也会有很多类型,所以我们使用模板的形式 //T,T&,T* //T,const...T&,const T* //设定了两种迭代器 template//记得每一个类前要写模板,可设置多个模板参数 struct list_iterator...  //T,T&,T* //T,const T&,const T* //设定了两种迭代器 template//记得每一个类前要写模板...里面去找const_iterator这个类型,但是Container是一个模板,并没有实例化,所以编译器也不知道怎么定义,所以就在编译的时候就过不了,但是我们在前面加一个typename就会告诉编译器,

    4510

    C++奇迹之旅:深度解析list的模拟实现

    前言 list节点 我们先建立一个列表里的节点类listnode,用来构造list的节点使用: // 这个宏定义用于禁用编译器的安全警告。...迭代器的设计: 对于 vector,迭代器通常是一个指向数组元素的指针(如 T*),可以直接进行指针运算。...对于 list,迭代器需要封装一个指向节点的指针(如 Node*),并提供自定义的 ++ 和 -- 操作符来遍历链表。这是因为在链表中,节点之间的关系是通过指针而不是通过内存地址的连续性来维护的。...迭代器的有效性: 在链表中,插入和删除操作可能会导致迭代器失效。使用 Node* 作为迭代器类型时,删除节点后,指向该节点的迭代器将变得无效。...() const { return const_Iterator(_head); } 这里实现const迭代器呢?

    6910

    深入剖析C++ STL中的set:高效管理有序数据的利器

    set 是 C++ STL 提供的一个模板类,基于红黑树实现,具有以下核心特性: 元素唯一:set 会自动去重,插入相同的元素时,新元素会被忽略。...自动排序:默认情况下,set 按照升序排列元素,也可以通过自定义比较器实现自定义排序。 高效操作:常见操作如插入、删除、查找的时间复杂度为 (log)。...set的构造和迭代器 set的构造我们关注以下几个接口即可。...set的支持正向和反向迭代遍历,遍历默认按升序顺序,因为底层是⼆叉搜索树,迭代器遍历⾛的中序;⽀持迭代器就意味着支持范围for,set的iterator和const_iterator都不支持迭代器修改数据...& val); // 删除⼀段迭代器区间的值 iterator erase (const_iterator first, const_iterator last); // 返回⼤于等于val位置的迭代器

    14010

    【STL】之 list 使用方法和模拟实现

    迭代器类: 下面我们来实现list的迭代器类 我们之前实现的string和vector的迭代器都是原生指针,直接typedef指针即可,因为前者的底层存储空间是连续的,这样我们在使用迭代器进行遍历时,可以直接用指针...但是list类不同,list底层实现是用一个一个节点组成,是我们自定义类型实现,没有办法保证地址连续,因此迭代器直接++就无用武之地了。...因此我们要将Node*进行运算符重载,但是Node*本身是一个指针,只有自定义类型才能用运算符重载,因此我们需要一个类将Node*封装起来,然后对Node*进行运算符的重载~ //List的迭代器类...而你可能会想说在创造一个const版本的迭代器类,这样固然是可以,但是这样会使得代码冗余!...这就是大佬设计的独到之处~ const_iterator自己可以修改,不是const对象,但是指向的内容不能修改 list类 在实现了迭代器之后,我们就可以正式手撕list类了。

    9010

    初识C++ · 模拟实现list

    : 一共三个自定义类型,分别是用来控制节点的,控制迭代器的,控制链表的,那么为什么会这么复杂呢?...++满足不了访问下一个空间的目的,那么为了能操纵迭代器的行为,我们这里就需要一个自定义类型,来让迭代器按照我们的想法去移动。...前言提及,对于链表的迭代器不是像普通迭代器一样那么简单,所以我们这里,需要创建一个迭代器类。 2 迭代器类 对于迭代器里面,我们要搞懂一个问题就是,这个类的用处是什么?成员变量有哪些?...相信这算得上一个难度,我们先抛开这个问题,先看如如何在链表里面存进这种类型的数据: void Test2_list() { list lt; A aa1(1, 2);//构造 A aa2 =...5 有关const迭代器 对于const迭代器来说,我们有一个简单粗暴的解决办法,就是重新创建一个类,原来的迭代器是ListIterator,const迭代器就叫ListConstIterator就好了

    6510

    【C++】用一棵红黑树同时封装出map和set

    红黑树的迭代器和list的迭代器实际是一个道理,两个容器的原生指针均无法满足迭代器的要求,所以道理还是相同,我们进行类封装+运算符重载,让类实例化后的对象能够满足迭代器的要求,使其行为像指针一样。...所以当const迭代器之间进行拷贝的时候,const迭代器类里面是没有写const迭代器之间的拷贝构造的,所以编译器会默认生成拷贝构造。...当普通迭代器之间进行拷贝的时候,普通迭代器类里面写了普通迭代器之间的拷贝构造,那么编译器就不会默认生成拷贝构造。...当const迭代器被普通迭代器拷贝的时候,const迭代器类里面的构造函数会被调用,即用普通迭代器构造出const迭代器。。...template class set { public: pair insert(const K& key)//这里的迭代器被替换为const_iterator

    48120

    【C++】STL---list

    ,const 迭代器和普通迭代器不是同一个类,不能直接在 iterator 前直接加 const,如 const iterator ,这不是 const 迭代器,因为这里的 const 修饰的是迭代器本身...,就是迭代器本身不能修改,但是我们期望的是迭代器本身可以被修改,如 it++、++it,只是期望迭代器指向的内容不能被修改,如 *it = 10、it->10 ; 这就类比 const T* 和 T*...3. list 反向迭代器类 list 的反向迭代器可以复用 list 的正向迭代器,就不需要我们重新写一个反向迭代器的类了。..._it; } 4. list 类 list 类首先将 const 迭代器和非 const 迭代器类型起别名为 const_iterator 和 iterator ,反向迭代器同上;成员变量有 _head...typedef 关键字,如 typename list::const_iterator it = lt.begin();;因为在模板还没有进行实例化的时候, const_iterator 就到

    9410

    【C++高阶】深度剖析:从零开始模拟实现 unordered 的奥秘

    ,则为K KeyOfT:通过T来获取key的一个仿函数类 HF: 哈希函数仿函数对象类型,哈希函数使用除留余数法,需要将Key转换为整形数字才能 取模 // unordered_set 与 unordered_set...HashTable的迭代器 迭代器基本设计 代码示例(C++): // 为了实现简单,在哈希桶的迭代器类中需要用到hashBucket本身,所以我们要进行一下前置声明,并且我们在 HashTable 中也要设置一个友元...end() const { return const_iterator(nullptr, this, -1); } ⭐迭代器的构造 因为我们引入了两个新的变量,所以此次构造与以往不同 代码示例(C...const迭代器上,都用 const来修饰K来起到不能修改K的特点 typedef typename hash_bucket::HashTable::const_iterator..._hashi),ret.second); } // 因为用到的都是const迭代器,所以非const迭代器我们可以不写 /*iterator begin() { return _ht.begin

    8010

    C++ STL 中的 map:高效管理键值对的有序容器

    自动排序:默认按键的升序排序,也可通过自定义比较器实现自定义排序。 唯一键:同一个 map 中,键不能重复。底层实现:基于红黑树,支持高效的增删改查,时间复杂度为 (log)。...map的⽀持正向和反向迭代遍历,遍历默认按key的升序顺序,因为底层是⼆叉搜索树,迭代器遍历⾛的中序;支持迭代器就意味着支持范围for,map支持修改value数据,不支持修改key数据,修改关键字数据...⼀个双向迭代器 iterator -> a bidirectional iterator to const value_type // 正向迭代器 iterator begin(); iterator...// 删除⼀段迭代器区间的值 iterator erase (const_iterator first, const_iterator last); // 返回⼤于等k位置的迭代器 iterator...lower_bound (const key_type& k); // 返回⼤于k位置的迭代器 const_iterator lower_bound (const key_type& k) const

    9610
    领券