Search code examples
c++for-loopiteratorstdmap

Get the previous or next item in a map from a for loop


I'm making a calculator that can accept more than one operator at once (e.g. 5x5x5). I have a map that contains the positions of the operators, and what type they are (x/+-). I also have a for loop for (auto const& [key, val] : oper_map) which I got from this post.

In order to get the left and right numbers, I need to know where the left and right operators are. I've attempted to use std::prev and std::next with the key like this:

int loper_pos = -1;
int roper_pos = 0;
double lnum;
double rnum;
char loper;
char roper;

//map defined elsewhere
for (auto const& [key, val] : oper_map)
{
    //loper is left operator while roper is right opeprator

    //tracks the position of the loop
    int map_pos = std::distance(oper_map.begin(), oper_map.find(key)); 

    if (map_pos == 0) loper_pos = -1;
    else
    {
        loper_pos = std::prev(key);
        loper = std::prev(val);
    }
    if (map_pos == oper_map.size()) roper_pos = oper_map.size() + 1;
    else
    {
        roper_pos = std::next(key);
        roper = std::next(val);
    }

but I guess it doesn't work since key isn't an iterator? I also can't increment/decrement key or val (or when using the C++11 version in this post), so I guess it doesn't count as an iterator? I don't know iterators confuse me.

This post appears to be what I want but for whatever reason lower_bound() does not work with oper_map; no suitable conversion.


Solution

  • No. key is not an iterator.

    for (auto const& [key, val] : oper_map)
    

    key is a const reference to the key in the map. If you want iterators, use iterators:

    for (auto it = oper_map.begin(); it != oper_map.end(); ++it) {
        auto next = std::next(it);
        auto prev = std::prev(it);
    }
    

    However, consider that std::map is not a sequential container. If you are interested in the positions of elements in the container, maybe a std::vector< std::pair<Key,MappedValue>> is more handy.