我正在学习使用 C++ 模板,stl
并且这个库包含一个类list<T>
,我知道它的功能类似于vector<T>
(如果没有,请举例说明)。
我的问题是,如何list<T>
在给定索引处访问类型对象中的元素?
到目前为止,我已经尝试过:
std::list<int> Numeros = /* Mi asignación aquí */;
int n = Numeros[0]; // Error.
但是,使用它std::vector<T>
可以完美地工作:
std::vector<T> Numeros = /* Alguna asignación */;
int n = Numeros[0]; // Asumiendo que tenemos un elemento aquí, me devuelve el valor.
list<T>
是否可以使用索引访问包含在 a中的值?
尽管所有 stl 容器在使用方面都有一定的相似之处,但事实是每个容器内部工作方式不同,因此并非所有方法都适用于所有容器。
std::vector
表示元素的无序列表。它的主要特点是所有元素在内存中都是连续的,允许随机访问。它是大多数情况下的默认容器。std::list
表示一个链表。作为一个链表它的元素不必在内存中是连续的,而是在访问第一个元素之前访问第二个元素。正是由于最后一个原因,它不支持随机访问,尽管它确实支持顺序访问。传统上,可以使用迭代器普遍遍历 STL 容器:
STL 中也有一些函数试图稍微封装这种机制:
std::foreach
: 遍历一个容器,并为每个元素执行一个由参数传递的函数std::transform
: 遍历一个容器,并为每个元素执行一个由参数传递的操作。上述操作的结果存储在一个新的容器中std::find
: 循环通过容器寻找参数传递的元素。返回元素的迭代器,如果未找到,则返回由下式给出的迭代器contenedor.end()
std::find_if
:与前一个类似,但它承认一个指向实现搜索条件的函数的指针std::reverse
:反转作为参数传递的迭代器之间的值(眼睛,在有序容器中,因为set
它们不起作用)由于 C++11 还提供了一种新类型的循环,它允许您轻松迭代容器,避免使用迭代器:
此外,从 C++11 开始,
std::begin
并且可用std::end
. 这两个函数允许在 STL 容器和固定大小的数组中获取相应的迭代器(它们的大小可以在编译时计算):使用迭代器的其他机制是:
std::distance
: 计算两个迭代器之间的元素个数std::next
: 允许将迭代器推进 n 个位置std::advance
:和上一个类似,它修改了作为参数传递的迭代器好吧,以上所有内容都是关于容器及其可能性的一些理论。
std::list
现在回答您的问题,是的,可以使用迭代器和std::next
or访问 a 和任何其他容器中的特定位置std::advance
。在 的特定情况下
std::list
,无法使用索引运算符访问特定元素,[]
因为它的元素不在连续的内存位置。访问一个随机元素意味着遍历列表的一部分节点,这个任务由迭代器执行并且必须明确地完成。一切顺利。
我浏览了文档
stl
和一些SO问题,我遇到std::advance()
了std::next()
:std::next(Vector, Numero)
:以可分配的方式返回索引(参数) 内的指针Numero
,返回与向量相同类型的元素。文档中,值得一提的是,没有这个参数Numero
这个函数会前进到Vector的下一个元素,所以这个参数是可选的。std::advance(Vector, Cantidad)
std::next()
:除了直接Vector
通过位于位置的元素修改参数Cantidad
并且不返回任何值外,它的工作原理几乎相同。文档示例
std::next(V,N)
:示例
std::advance(V,N)
:值得一提的是
Cantidad
,我在其中命名的参数std::advance()
是强制性的。int_list.begin()
在列表的开头放置一个指针int_list.end()
是指向列表末尾的指针使用指针算法将列表开头的指针移动到下一个元素:
list_iter++