gpt4 book ai didi

c++ - 带有指向自身的指针的 forward_list 结构

转载 作者:行者123 更新时间:2023-11-30 01:40:50 25 4
gpt4 key购买 nike

我正在实现一个非常简单的图模型,其中我有一个包含前向列表的结构,该列表带有指向它的邻居的指针。这些邻居又是相同类型的结构。

#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 函数)我收到此错误:

error: no viable conversion from 'const_iterator' (aka '__forward_list_const_iterator *>') to 'Neighbors::iterator' (aka '__forward_list_iterator *>')

提前致谢。

最佳答案

此错误的原因非常微妙。 std::setiterator type 实际上与其 const_iterator 相同类型。这是有道理的;集合需要始终保证每个元素都是唯一的。如果您可以自由修改元素,它就无法提供这种保证。

考虑以下行:

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

it是一个 iterator就像const_iterator .您不能修改迭代器指向的内容。

您可以按如下方式验证:

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

然后是这一行:

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

it->_nextforward_list<Vertex*> const由于上述原因,并调用begin()因此在其上返回 const_iterator .

这就是最终导致错误的原因:您无法转换 const_iteratoriterator .

治愈很简单:只需使用 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++)。

关于c++ - 带有指向自身的指针的 forward_list 结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42583478/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com