簡體   English   中英

使用帶有指向自身的指針的forward_list進行結構

[英]Struct with forward_list with pointers to itself

我正在實現一個非常簡單的圖形模型,其中有一個結構,該結構包含帶有指向其鄰居的指針的轉發列表。 這些鄰居又是相同類型的結構。

#include <iostream>
#include <vector>
#include <set>
#include <forward_list>
#include <fstream>

using namespace std;

typedef struct Vertex Vertex;

struct Vertex {
    unsigned id;
    forward_list<Vertex*> _next;
};

typedef set<Vertex> Graph;
typedef vector<Vertex*> Index;
typedef pair<unsigned, unsigned> Edge;
typedef forward_list<Vertex*> Neighbors;


// Function:    process_line()
// Purpose:     process a specific line from the file.
// Params:      line to process
Edge process_line(string line){
    unsigned vertex_from;
    unsigned vertex_to;

    int idx = line.find(" ");

    vertex_from = (unsigned)stoul(line.substr(0, idx));
    vertex_to = (unsigned)stoul(line.substr(idx+1, line.length()));

    return make_pair(vertex_from, vertex_to);
}


// Function:    load_graph()
// Purpose:     load graph from file in relation
// Params:      path, and reference to graph and index
bool load_graph(string file_path, Graph &graph, Index &index){
    string line;
    ifstream file(file_path);
    bool foundEmptyLine = false;

    if(file.is_open()){
        while(getline(file, line)){
            if(line.empty()){
                foundEmptyLine = true;
            }

            if(!foundEmptyLine){
                // processing vertexes
                Vertex *vertex = new Vertex;

                vertex->id = stoul(line);
                graph.emplace(*vertex);
                index.emplace_back(vertex);
            }else{
                // Processing relations
                Edge edge = process_line(line);
                Vertex* neighbor = index.at(edge.second);

                // Lookup edge in index
                index.at(edge.first)->_next.push_front(neighbor);
            }
        }
        file.close();
    }else{
        cout << "Unable to open " << file_path;
        return false;
    }

    return true;
}

void print_graph(Graph &graph){
    for(Graph::iterator it = graph.begin(); it != graph.end(); ++it){
        // Print item.
        cout << "Node: " << it->id << endl << "Neighbors:";

        for(Neighbors::iterator neigh = it->_next.begin(); neigh != it->_next.end(); ++neigh){
            // Print item.
            cout << (*neigh)->id;
        }
    }
}


// Entry point.
int main() {
    Graph graph;
    Index index;

    load_graph("graph_1.txt", graph, index);


    print_graph(graph);
}

一切都完成了,直到我嘗試循環圖中的頂點,然后循環頂點的所有鄰居。 (print_graph函數)出現此錯誤:

錯誤:沒有從'const_iterator'(aka'__forward_list_const_iterator *>')到'Neighbors :: iterator'(aka'__forward_list_iterator *>')的可行轉換

提前致謝。

問題是

Graph::iterator it = graph.begin()

將返回Graph::iterator類型的迭代器,該迭代Graph::iterator等於Graph::const_iterator 請參閱http://en.cppreference.com/w/cpp/container/set (請注意,這在C ++ 11中已更改)。

所以當你再打電話

Neighbors::iterator neigh = it->_next.begin()

這將返回一個std::forward_list::const_iterator (因為*itconst ),您當然不能將其分配給std::forward_list::iterator

無論如何,我建議在這里為這些類型使用auto ,並且由於無論如何都不需要寫訪問,因此應該使用cbegin() ,無論如何它都會返回const_iterator

此錯誤的原因非常微妙。 std::setiterator類型實際上與const_iterator類型相同。 這很有道理; 一個集合需要始終保證每個元素都是唯一的。 如果您可以自由修改元素,則將無法提供保證。

考慮以下行:

 for(Graph::iterator it = graph.begin(); it != graph.end(); ++it){ 

it是一個類似於const_iteratoriterator 您無法修改迭代器指向的對象。

您可以如下驗證:

it->id = 1; // will result in a compilation error

然后是這一行:

  for(Neighbors::iterator neigh = it->_next.begin(); neigh != it->_next.end(); ++neigh){ 

由於上述原因, forward_list<Vertex*> const it->_nextforward_list<Vertex*> const ,因此在其上調用begin()會返回const_iterator

最終導致錯誤的原因是:您不能將const_iterator轉換為iterator

治愈很容易:只需使用const_iterator

for(Neighbors::const_iterator neigh = it->_next.begin(); neigh != it->_next.end(); ++neigh){

甚至更好,使用auto

for(auto neigh = it->_next.begin(); neigh != it->_next.end(); ++neigh){

甚至更簡單,基於范圍的for循環:

for (auto const& neigh : it->_next) {
    // Print item.
    cout << neigh->id;
}

請注意,解決此特定錯誤后,您將找到其他錯誤。 您還缺少必要的#include <string> ,它使您的代碼依賴於平台(即,它適用於GCC,但不適用於Visual C ++)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM