Accessing map value by index
Your map
is not supposed to be accessed that way, it's indexed by keys not by positions. A map
iterator is bidirectional, just like a list
, so the function you are using is no more inefficient than accessing a list
by position. If you want random access by position then use a vector
or a deque
.
Your function could be written with help from std::advance(iter, index)
starting from begin()
:
auto it = myMap.begin();
std::advance(it, index);
return it->first;
There may be an implementation specific (non-portable) method to achieve your goal, but not one that is portable.
In general, the std::map
is implemented as a type of binary tree, usually sorted by key. The definition of the first element differs depending on the ordering. Also, in your definition, is element[0] the node at the top of the tree or the left-most leaf node?
Many binary trees are implemented as linked lists. Most linked lists cannot be directly accessed like an array, because to find element 5, you have to follow the links. This is by definition.
You can resolve your issue by using both a std::vector
and a std::map
:
- Allocate the object from dynamic memory.
- Store the pointer, along with the key, into the
std::map
. - Store the pointer in the
std::vector
at the position you want it at.
The std::map
will allow an efficient method to access the object by key.
The std::vector
will allow an efficient method to access the object by index.
Storing pointers allows for only one instance of the object instead of having to maintain multiple copies.
Well, actually you can't. The way you found is very unefficient, it have a computational complexity of O(n) (n operations worst case, where n is the number of elements in a map).
Accessing an item in a vector or in an array have complexity O(1) by comparison (constant computational complexity, a single operation).
Consider that map is internally implemented as a red black tree (or avl tree, it depends on the implementation) and every insert, delete and lookup operation are O(log n) worst case (it requires logarithm in base 2 operations to find an element in the tree), that is quite good.
A way you can deal with is to use a custom class that have inside both a vector and a map. Insertion at the end of the class will be averaged O(1), lookup by name will be O(log n), lookup by index will be O(1) but in this case, removal operation will be O(n).