Although all the containers of the stl keep certain similarities regarding the use the certain thing is that each one internally works of different form, soon all the methods are not going to be available in all the 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 Your items do not have to be contiguous in memory but to access the second item before you have to access the first. It is for this last reason why it does not admit random access although it does admit the sequential one.
Traditionally STL containers can be traversed universally using iterators:
for( auto it = contenedor.begin(); it != contenedor.end(); ++it )
{
// ...
}
There are also functions within the STL that try to encapsulate this mechanics a bit:
-
std::foreach
: Walk through a container and, for each element, execute a function passed by parameter
-
std::transform
: It traverses a container and, for each element, executes an operation passed by parameter. The result of this operation is stored in a new container
-
std::find
: It traverses a container looking for an element passed by parameter. Returns an iterator to the element or, if it is not found, the iterator given by contenedor.end()
-
std::find_if
: Similar to the previous one but it supports a pointer to a function that implements the search criteria
-
std::reverse
: Inverts the values that are between the iterators passed as a parameter (eye, in ordered containers, as set
will not work)
- ...
A new type of loop is also available from C ++ 11 that allows easy iteration over containers avoiding the use of iterators:
std::vector<int> lista(10);
std::iota(lista.begin(), lista.end(), 1);
for( auto item : lista )
std::cout << item << std::endl;
Also, from C ++ 11, std::begin
and std::end
are available. These two functions allow you to obtain the corresponding iterators both in STL containers and in fixed size arrays (you can calculate their size at compile time):
std::vector<int> v = {1,2,3,4,5};
int arreglo[] = {6,7,8,9,10};
for( auto it = std::begin(v); it != std::end(v); ++it )
std::cout << *it;
for( auto it = std::begin(arreglo); it != std::end(arreglo); ++it )
std::cout << *it;
Other mechanisms to work with iterators are:
-
std::distance
: Calculate the number of elements between two iterators
-
std::next
: It allows advancing an iterator n positions
-
std::advance
: Similar to the previous one, modify the last iterator as parameter
Well, all of the above was a bit of theory about the contenders and their possibilities. Answering your question now, yes, it is possible to access a specific position of both a std::list
and any other container using iterators and std::next
or std::advance
.
In the specific case of std::list
, it is not possible to access a specific element using the index operator []
because its elements are not in consecutive memory positions. Accessing a random element involves traversing a part of the nodes in the list and that task is performed by iterators and must be carried out explicitly.
Greetings.