C++使用auto与定义的迭代器

mcd*_*o13 0 c++ iterator auto c++11

任何人都可以在我的代码中解释for循环的差异吗?我知道迭代器是指向某些数据的指针,当我输入"*iter"时,我正在访问该指针指向的值(一个int).但我不明白为什么汽车在这里不会以同样的方式工作.为什么我不需要在另一个for循环中取消引用顶点?

#include <iostream>
#include <list>
#include <queue>

class Graph {
    public:
        Graph(int num_v): num_vertices(num_v), adj_list(new std::list<int>[num_v]) {}

        void add_edge(int u, int v) { adj_list[u].push_back(v); }

        void bfs_traversal(int start) {
            bool* visited = new bool[num_vertices];
            for (int i = 0; i < num_vertices; i++)
                visited[i] = false;
            std::queue<int> q;
            visited[start] = true;
            q.push(start);
            //std::list<int>::iterator iter;
            while(! q.empty()) {
                int node = q.front();
                std::cout << node << " ";
                q.pop();

                /*
                for (iter = adj_list[node].begin(); iter != adj_list[node].end(); ++iter) {
                    if (! visited[*iter]) {
                        visited[*iter] = true;
                        q.push(*iter);
                    }
                */

                for (auto vertex : adj_list[node]) {
                    if (! visited[vertex]) {
                        visited[vertex] = true;
                        q.push(vertex);
                    }
                }

            }
        }

    private:
        int num_vertices;
        std::list<int>* adj_list;
};

int main() 
{
    Graph graph(4);
    graph.add_edge(0,1);
    graph.add_edge(0,2);
    graph.add_edge(1,2);
    graph.add_edge(2,0);
    graph.add_edge(2,3);
    graph.add_edge(3,3);

    std::cout << "breadth first traversal starting from vertex 2\n";

    graph.bfs_traversal(2);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译:g ++ -std = c ++ 11 source:https://www.geeksforgeeks.org/breadth-first-traversal-for-a-graph/

Bat*_*eba 5

未注释的版本使用基于范围的 for循环.

请注意,存在细微差别; 与迭代器版本不同,它vertex是容器元素的值副本.正是出于这个原因

for (const auto& vertex : adj_list[node]) {
Run Code Online (Sandbox Code Playgroud)

在使用较大的容器类型时,甚至是更好的容器是首选auto&& vertex.

在引擎盖下,基于范围的表示法使用迭代器.因此,重要的是要记住迭代器失效的C++ 03规则仍然适用.


You*_*You 5

因为基于范围的for循环适合您.在这种特定情况下(假设是),需要生成与以下内容等效的代码(变量名仅用于说明):

{
  auto && __range = adj_list[node]; 
  for (auto __begin = __range.begin(), __end = __range.end(); 
       __begin != __end; ++__begin) { 
    auto vertex = *__begin; 
    // ... 
  } 
}
Run Code Online (Sandbox Code Playgroud)

注意第5行,其中在解除引用迭代器之后进行复制.


正如@Bathsheba指出的那样,很可能你想要const auto&而不仅仅是auto.