List的使用

库里面的链表如下

cplusplus.com/reference/list/list/?kw=list

首先可以知道的是,库里面的list是双向循环链表,那么在定义节点时,就有三个成员,指向上一个节点的prev,指向下一个节点的next和节点本身的数据。当想要存储各种类型时,为避免代码冗余和增加我们的工作量,使用模板就可以很好的适配出我们想要的类型

cpp 复制代码
	template<class T>
	struct ListNode
	{
		ListNode(const T& val = T())
			: _prev(nullptr)
			, _next(nullptr)
			, _val(val)
		{}

		ListNode<T>* _prev;
		ListNode<T>* _next;
		T _val;
	};

和vector一样,list也是一种容器,但vector的迭代器很容易实现,因为vector的物理空间都是连续的,而物理空间不连续的list容器,它的迭代器的实现不简单。

在list迭代器中,我们期望他完成++,--,*等操作,而在判断迭代器是否继续走时时,不应该用<来判断,list不连续所以只能用!=操作判断。

但还有一种情况,如果list迭代器指向的内容,只读而不能修改它,那该怎么办?

方法一:使用const_iterator

cpp 复制代码
#include <list>
#include <iostream>

int main() {
    std::list<int> myList = {1, 2, 3, 4, 5};
    for (std::list<int>::const_iterator it = myList.cbegin(); it != myList.cend(); ++it) {
        std::cout << *it << " "; 
    }
    for (auto it = myList.cbegin(); it != myList.cend(); ++it) {
        std::cout << *it << " ";
    }
}

方法二:使用const引用或const容器

如果容器本身是由const修饰的,他的迭代器会自动变成const_iterator

cpp 复制代码
const std::list<int> myList = {1, 2, 3, 4, 5};
for (auto it = myList.begin(); it != myList.end(); ++it) {
    std::cout << *it << " "; // 只读
    // *it = 10;             // 错误
}