I am learning to use C++ templates from stl
and this library contains a class list<T>
, I understand that it has functions similar to those of vector<T>
(If not, please illustrate me) .
My question is, how can I access an element within an object of type list<T>
at a given index?
So far I have tried this:
std::list<int> Numeros = /* Mi asignación aquí */;
int n = Numeros[0]; // Error.
However, using it std::vector<T>
works perfectly:
std::vector<T> Numeros = /* Alguna asignación */;
int n = Numeros[0]; // Asumiendo que tenemos un elemento aquí, me devuelve el valor.
Is it possible to access the values contained within a list<T>
using an index?
Although all the stl containers have certain similarities in terms of use, the truth is that each one internally works differently, so not all methods will be available in all containers.
std::vector
represents an unordered list of elements. Its main characteristic is that all the elements are contiguous in memory, which allows random access. It is the default container for most situations.std::list
represents a linked list. Being a linked list Its elements do not have to be contiguous in memory but to access the second element before you have to access the first. It is for this last reason that it does not support random access although it does support sequential access.Traditionally STL containers can be traversed universally using iterators:
There are also functions within the STL that try to encapsulate this mechanic a bit:
std::foreach
: Iterates through a container and, for each element, executes a function passed by parameterstd::transform
: Iterates through a container and, for each element, executes an operation passed by parameter. The result of said operation is stored in a new containerstd::find
: Loop through a container looking for an element passed by parameter. Returns an iterator to the element or, if not found, the iterator given bycontenedor.end()
std::find_if
: Similar to the previous one but it admits a pointer to a function that implements the search criteriastd::reverse
: Inverts the values that are between the iterators passed as a parameter (eye, in ordered containers, sinceset
they will not work)Since C++11 a new type of loop is also available that allows you to easily iterate over containers avoiding the use of iterators:
Also, since C++11,
std::begin
and are availablestd::end
. These two functions allow to obtain the corresponding iterators both in STL containers and in fixed-size arrays (their size can be calculated at compile time):Other mechanisms for working with iterators are:
std::distance
: Calculates the number of elements between two iteratorsstd::next
: Allows to advance an iterator n positionsstd::advance
: Similar to the previous one, it modifies the iterator passed as parameterWell, all of the above was a bit of theory about the containers and their possibilities. Now answering your question, yes, it is possible to access a specific position both in a
std::list
and in any other container using iterators andstd::next
orstd::advance
.In the specific case of
std::list
, it is not possible to access a specific element using the indexing operator[]
because its elements are not in consecutive memory locations. Accessing a random element implies traversing a part of the nodes of the list and this task is carried out by iterators and has to be done explicitly.All the best.
I have wandered through the documentation
stl
and some SO questions , I have come acrossstd::advance()
andstd::next()
:std::next(Vector, Numero)
: Returns a pointer within the index (Parameter)Numero
in an assignable way, returns an element of the same type of the vector. Documentation , it is worth mentioning that without the parameterNumero
this function advances to the next element of the Vector, so this parameter is optional.std::advance(Vector, Cantidad)
: It works practically the same asstd::next()
except that it directly modifies the parameterVector
by the element located in the positionCantidad
and does not return any value. DocumentationExample with
std::next(V,N)
:Example with
std::advance(V,N)
:It is worth mentioning that the parameter
Cantidad
that I have named instd::advance()
is mandatory.int_list.begin()
place a pointer at the beginning of the listint_list.end()
is a pointer to the end of the listThe pointer at the start of the list is moved to the next element with pointer arithmetic:
list_iter++