重命名地图迭代器的第一个和第二个

use*_*655 19 c++ iterator stl map

有没有办法重命名map迭代器的第一个和第二个访问器函数.我知道他们有这些名称是因为代表键和值的底层对,但我希望迭代器更具可读性.我认为这可能是使用迭代器适配器,但我不知道如何实现它.

请注意,我不能使用提升.

我的意思是:

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
}
Run Code Online (Sandbox Code Playgroud)

Geo*_*che 20

如果您只关心可读性,可以执行以下操作:

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

然后:

Vertex v = adjacency(it).vertex;
Run Code Online (Sandbox Code Playgroud)


Kei*_*thB 13

您无法重命名成员,但可以使用某些功能来提供帮助.

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

然后,it->vertex你可以做,而不是你想要的vertex(it)

  • +1还为const_iterators添加重载. (2认同)

rlb*_*ond 7

很不幸的是,不行.我通常做的是:

typedef map<Vertex, Edge> AdjacencyList;
typedef AdjacencyList::value_type Vertex_Edge_Pair;
Run Code Online (Sandbox Code Playgroud)

为了便于阅读.在你的循环内你也可以说

Vertex& current_vertex = it->first;
Edge& current_edge = it->second;
Run Code Online (Sandbox Code Playgroud)


sch*_*ter 7

如果您不需要迭代器(例如,基于范围的 for 循环适合您的目的),那么从c++17开始,您可以使用结构化绑定

map<Vertex, Edge> adjacency_list;
for( auto & [ vertex, edge ] : adjacency_list )
{
    // do stuff with vertex
}
Run Code Online (Sandbox Code Playgroud)


Mic*_*ker 6

当然,重新实现或包装迭代器,但值得努力吗?岂不

Vertex& v = it->first;
Run Code Online (Sandbox Code Playgroud)

更容易?

  • 还要记住,使用std :: map迭代器的第一个和第二个是一个常见的习惯用法,你会混淆任何阅读你代码的人 - 有点. (4认同)
  • 这是真的,但从理智的角度来看,"第一"和"第二"足够令人困惑;-) (3认同)