如何解决Boost::BGL模板<->类循环依赖?

发布于 2024-10-03 11:20:10 字数 832 浏览 7 评论 0 原文

我在使用 Boost 图形库的邻接列表时遇到问题。这似乎是一个循环依赖问题: 我有一个使用某个类 A 的模板的 typedef T。另外,A 存储了一个指向 T 类型对象的指针。现在编译器告诉我,T 没有命名类型。

以下是我的更具体文件的摘录:

//graphdefinitions.hpp
#include "lane.hpp"
#include "tie.hpp"

typedef boost::adjacency_list<boost::listS, boost::listS, 
                              boost::directedS, Tie, Lane> Map;
typedef boost::graph_traits<Map>::edge_descriptor edge_descriptor;

//lane.hpp
#include "graphdefinitions.hpp"
class Lane {
    ...
    edge_descriptor *left, *right;
};

//tie.hpp
//no important includes here
class Tie {
    ...
};

如何解决此依赖性/包含顺序问题?

另一个编辑: 我只是想到,edge_descriptor 的类型可能是像 int 这样的原始类型。这本来可以解决问题,因为我可以用普通的 int 变量替换 Lane 的 edge_descriptors,从而可以删除在 tie.hpp 中包含 graphdefinitions.hpp。不幸的是我的想法很糟糕,我必须找到另一个解决方案。 Edge_descriptor 类型的存在似乎是有原因的......

I have a problem with using the adjacency-list of the Boost Graphics Library. It seems to be a circular dependency problem:
I have a typedef T of a template which uses some class A. Additionally A stores a pointer to an object of type T. Now the compiler tells me, that T does not name a type.

Here are excerptions of my more concrete files:

//graphdefinitions.hpp
#include "lane.hpp"
#include "tie.hpp"

typedef boost::adjacency_list<boost::listS, boost::listS, 
                              boost::directedS, Tie, Lane> Map;
typedef boost::graph_traits<Map>::edge_descriptor edge_descriptor;

//lane.hpp
#include "graphdefinitions.hpp"
class Lane {
    ...
    edge_descriptor *left, *right;
};

//tie.hpp
//no important includes here
class Tie {
    ...
};

How do I solve this dependency / inclusion-order problem?

ANOTHER EDIT:
I just had the idea that the type of an edge_descriptor might be a primitive one like int. That would have solved the problem because I would have been able to replace the edge_descriptors of Lane by plain int-variables and thus could have removed the inclusion of graphdefinitions.hpp inside tie.hpp. Unfortunately my idea was cra* and I have to find another solution. Edge_descriptor types seem to be there for a reason...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

香橙ぽ 2024-10-10 11:20:10

BGL 中有一个没有详细记录的特征类,它可以为 adjacency_list 图提供顶点和边描述符类型,而无需知道属性类型。它专为您所拥有的用例而设计。查看 http:// 的“关联类型”部分www.boost.org/doc/libs/1_45_0/libs/graph/doc/adjacency_list.html 并注意 vertex_descriptoredge_descriptor 有两个定义;您可以在属性包的定义中使用来自 adjacency_list_traits 的版本,而不会导致循环定义。

There is a not-well-documented traits class in BGL that gives the vertex and edge descriptor types for an adjacency_list graph without needing to know the property types. It is designed for exactly the use case you have. Look in the "Associated Types" section of http://www.boost.org/doc/libs/1_45_0/libs/graph/doc/adjacency_list.html and notice that there are two definitions for vertex_descriptor and edge_descriptor; you can use the versions that come from adjacency_list_traits in the definitions of your property bundles without causing a circular definition.

心奴独伤 2024-10-10 11:20:10

您已循环包含标题。车道包括图形定义,车道包括图形定义,等等。这就是你的问题的原因。

编辑:我意识到OP中已经提到了这一点。这个问题的解决方案是PIMPL。

编辑:我实际上要做的是将 typedef 放在 Lane 类中。这应该以最巧妙的方式解决问题。

You have circularly included headers. Lane includes graphdefinitions, which includes lane, which includes graphdefinitions, etc. This is the cause of your problem.

Edit: I realized this was already mentioned in the OP. The solution to this problem is PIMPL.

Edit: What I would actually do is put the typedef inside the Lane class. That should solve the problem in the neatest way.

残龙傲雪 2024-10-10 11:20:10

我真的不认为你需要这段代码有什么特别的。您必须确保图中使用的类型的定义已声明(而不仅仅是前向声明)。

I really don't think you need anything special about this code. You have to make sure the definitions of the types used in the graph are declared (not only forward-declared).

若无相欠,怎会相见 2024-10-10 11:20:10

@DeadMG:我现在使用了类似 PIMPL 的方法,我认为这解决了我的问题。

那么我做了什么?
我将 Lane-class 更改为如下所示:

//lane.hpp
#include "graphdefinitions.hpp"

class LaneSide;
class Lane {
public:
    const LaneSide getLeft() const;
    const LaneSide getRight() const;
    ...
private:
    LaneSide *left;
    LaneSide *right;
    ...
};

LaneSide-class 实际上只是一个间接寻址,并保存我无法在 Lane.hpp 内转发声明的值的类型,如下所示:

//laneside.hpp
class LaneSide
{
    edge_descriptor* edge;
};

这似乎欺骗了编译器正如我的意图。所以感谢 DeadMG 的提示。我想知道的是:是否也可以将 LaneSide 对象存储在 Lane 类中,而不是作为指针,而是作为真实对象?我首先尝试了这个,但编译器抱怨这个构造。我还想知道是否有办法避免额外的内存消耗。当我的图表变得足够大时,这最终可能会变得相关。

@DeadMG: I used a PIMPL-like approach now and I think that this solved my problem.

So what did I do?
I changed my Lane-class to look this way:

//lane.hpp
#include "graphdefinitions.hpp"

class LaneSide;
class Lane {
public:
    const LaneSide getLeft() const;
    const LaneSide getRight() const;
    ...
private:
    LaneSide *left;
    LaneSide *right;
    ...
};

And the LaneSide-class which is practically just an indirection and holds the type of value that I could not forward declare inside of lane.hpp, looks this way:

//laneside.hpp
class LaneSide
{
    edge_descriptor* edge;
};

This seems to trick the compiler as I intended to. So thank you for the hint DeadMG. What I was wondering: Is it also possible to store a LaneSide-object inside of the Lane-class not as a pointer but rather as a real object? I tried this first but the compiler complained about the construction. And I'm also wondering whether there might be a way to avoid the additional memory consumption. When my graph gets big enough this might eventually become relevant.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文