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

时间:2018-01-16 10:11:48

标签: c++ c++11 iterator auto

有人能解释我代码中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;
}

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

2 个答案:

答案 0 :(得分:5)

未注释的版本使用基于范围的 new InputStreamReader()循环。

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

vertex
使用较大的容器类型,甚至是for (const auto& vertex : adj_list[node]) { 时,

是首选。

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

答案 1 :(得分:5)

因为range-based for-loop为你做了。在这种特定情况下(假设),需要生成与以下内容等效的代码(变量名仅用于展示):

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

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

正如@Bathsheba指出的那样,您可能需要const auto&而非auto