Как объявить две структуры, у которых есть члены типа других?

Я пытаюсь создать ориентированный граф, поэтому я создал класс 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

Как я могу обойти это?

0

Решение

Просто используйте предварительная декларация:

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 ) {}
};

// ...
};

Вот полный живой пример из вышеупомянутой компиляции кода.

4

Другие решения

Вы встраиваете GNode* в вашем GEdge, Для этого не нужно определение структуры, все указатели структуры представлены одинаково, поэтому компилятор уже знает все, что ему нужно. Вы встраиваете полный GEdgeS в (вектор в) ваш 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; };

Я просто рефлексивно структурирую вперед, в любом случае это мне помогает.

2

По вопросам рекламы [email protected]