Я пытаюсь создать ориентированный граф, поэтому я создал класс Graph, и у него есть структура частного края и структура частного узла. Я хотел бы, чтобы у моих ребер был элемент узла, который является узлом, на который указывает ребро, и я хотел бы, чтобы у моих узлов был список всех ребер, которые ведут от них.
#ifndef DIRECTED_GRAPH_H
#define DIRECTED_GRAPH_H
#include <iostream>
#include <vector>
#include <string>
class Graph {
public:
Graph( const std::string & );
~Graph();
void print();
private:
struct GNode
{
std::string currency_type;
std::vector<GEdge> edges; // line 19
GNode( std::string name ) : currency_type( name ) {}
};
struct GEdge
{
int weight;
GNode * node; // node that the edge is pointed towards
GEdge( int weight, GNode* node ) : weight( weight ), node( node ) {}
};
GNode *source;
std::vector<GNode> nodes;
void add_node( const std::string & currency );
void add_edge( const GNode *& source, const GNode *& destination, int weight );
std::string bellman_ford( const GNode *&source );
};
#include "directed_graph.cpp"
#endif
Проблема в том, что в этом случае объявляется первая структура GNode
не знает, что GEdge
существует, что заставляет компилятор выдавать мне ошибку
directed_graph.h:19: error: ISO C++ forbids declaration of ‘vector’ with no type
Как я могу обойти это?
Просто используйте предварительная декларация:
class Graph {
// ...
private:
struct GEdge;
// ^^^^^^^^^^^^^
// Forward declaration for GEdge
struct GNode
{
std::string currency_type;
std::vector<GEdge> edges; // <== This is now OK because of the
// forward declaration above
GNode( std::string name ) : currency_type( name ) {}
};
struct GEdge // <== Now comes the definition of GEdge
{
int weight;
GNode * node; // node that the edge is pointed towards
GEdge( int weight, GNode* node )
: weight( weight ), node( node ) {}
};
// ...
};
Вот полный живой пример из вышеупомянутой компиляции кода.
Вы встраиваете GNode*
в вашем GEdge
, Для этого не нужно определение структуры, все указатели структуры представлены одинаково, поэтому компилятор уже знает все, что ему нужно. Вы встраиваете полный GEdge
S в (вектор в) ваш GNode
, Это требует полного определения структуры в некоторый момент, с вектором, который он откладывает, но если вы решили переключиться на std::array<>
он потерпит неудачу, если GEdge еще не будет определен.
Поменяйте местами порядок определения и добавьте предварительную декларацию:
#include <vector>
struct GNode;
struct GEdge { GNode *n; };
struct GNode { std::vector<GEdge> e; };
Это имеет преимущество работы, даже если вы не получаете помощь от vector<GEdge>
отложенная конструкция выделения кучи:
struct GNode;
Struct GEdge { GNode *n; };
struct GNode { GEdge e; };
Я просто рефлексивно структурирую вперед, в любом случае это мне помогает.