Renaming first and second of a map iterator

10,004

Solution 1

If you're just concerned about readability you could do something like this:

typedef map<Vertex, Edge> AdjacencyList;
struct adjacency
{
    adjacency(AdjacencyList::iterator& it) 
      : vertex(it->first), edge(it->second) {}
    Vertex& vertex;
    Edge& edge;
};

And then:

Vertex v = adjacency(it).vertex;

Solution 2

You can't rename the members, but you can have some functions to help.

inline Vertex& vertex(map<Vertex, Edge>::iterator& it) {return it->first;}
inline Edge& edge(map<Vertex, Edge>::iterator& it) {return it->second;}

Then, instead of it->vertex like you want, you can do vertex(it)

Solution 3

Unfortunately, no. What I usually do is this:

typedef map<Vertex, Edge> AdjacencyList;
typedef AdjacencyList::value_type Vertex_Edge_Pair;

For readability. Inside your loop you can also say

Vertex& current_vertex = it->first;
Edge& current_edge = it->second;

Solution 4

Sure, reimplement or wrap iterator, but is it worth the effort? Wouldn't

Vertex& v = it->first;

be easier?

Solution 5

If you don't need the iterator (e.g., a range-based for loop suits your purpose), then as of c++17 you can use structured bindings:

map<Vertex, Edge> adjacency_list;
for( auto & [ vertex, edge ] : adjacency_list )
{
    // do stuff with vertex
}
Share:
10,004
user281655
Author by

user281655

Updated on June 16, 2022

Comments

  • user281655
    user281655 almost 2 years

    Is there any way to rename the first and second accessor functions of a map iterator. I understand they have these names because of the underlying pair which represents the key and value, but I'd like the iterators to be a little more readable. I think this might be possible using an iterator adaptor, but I'm not sure how to implement it.

    Please note that I can't use boost.

    Example of what I mean:

    map<Vertex, Edge> adjacency_list;
    for(map<Vertex, Edge>::iterator it = adjacency_list.begin();
        it != adjacency_list.end();
        ++it)
    {
        Vertex v = it->first;
        //instead I would like to have it->vertex
    }
    
  • phoku
    phoku over 14 years
    Also remember that using first and second of the std::map iterator is such a common idiom that you'd confuse anyone reading your code - a bit.
  • Michael Krelin - hacker
    Michael Krelin - hacker over 14 years
    That true, but from the sanity perspective, first and second are confusing enough ;-)
  • user1353535
    user1353535 over 6 years
    Nobody else suggested this because it's a terrible idea.
  • Himanshuman
    Himanshuman over 2 years
    Why no one suggests this?
  • Jarek C
    Jarek C almost 2 years
    It is requested to use it->vertex (not just v). So the answer IHMO should not be "sure", but rather "somewhat".
  • Michael Krelin - hacker
    Michael Krelin - hacker almost 2 years
    @JarekC, sure, you have a point, but I still think "sure" sounds better :)