【问题标题】:How to declare two structs which have members of the others type?如何声明两个具有其他类型成员的结构?
【发布时间】:2013-05-06 23:08:48
【问题描述】:

我正在尝试制作一个有向图,所以我制作了一个 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

我该如何解决这个问题?

【问题讨论】:

  • 你为什么不做std::vector&lt;GEdges&gt;?
  • 我应该,并且会

标签: c++ directed-graph


【解决方案1】:

只需使用forward declaration:

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

    // ...
};

这是上面代码编译的完整live example。

【讨论】:

  • 我如何将成员添加到 GEdge?
  • @Loourr:稍后可以添加GEdge的定义。我要更新答案了
  • @Loourr:给你,我还添加了一个现场示例的链接
  • @Loourr:很高兴它有帮助:)
【解决方案2】:

您在您的GEdge 中嵌入了GNode*。这不需要结构定义,结构指针都表示相同,因此编译器已经知道它需要的一切。您将完整的GEdges 嵌入到您的GNode(向量中)。在某些时候需要一个完整的结构定义,它的向量被延迟,但如果你决定切换到std::array&lt;&gt;,如果 GEdge 尚未定义,它将失败。

交换定义顺序并添加前向声明:

#include <vector>
struct GNode;
struct GEdge { GNode *n; };
struct GNode { std::vector<GEdge> e; };

即使您没有从vector&lt;GEdge&gt; 堆分配的延迟构造中获得帮助,这也具有工作的优势:

struct GNode;
Struct GEdge { GNode *n; };
struct GNode { GEdge e; };

我只是反射性地对结构进行前向处理,无论如何它对我有帮助。

【讨论】:

  • 当然你必须记住,在你真正定义它之前,你不能使用除了指针(或双指针等)之外的任何东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-18
  • 2013-09-07
  • 2012-10-22
  • 1970-01-01
  • 2020-09-02
  • 1970-01-01
  • 2014-01-06
相关资源
最近更新 更多