Как решить круговую зависимость Boost :: BGL template <-> класса? - PullRequest
3 голосов
/ 20 ноября 2010

У меня проблема с использованием списка смежности графической библиотеки Boost.Кажется, это проблема циклической зависимости: у меня есть typedef T шаблона, который использует некоторый класс A. Кроме того, 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.Это решило бы проблему, потому что я мог бы заменить edge_descriptors Lane на простые int-переменные и, таким образом, мог бы удалить включение graphdefinitions.hpp внутри tie.hpp.К сожалению, моя идея была безумной *, и я должен найти другое решение.Типы Edge_descriptor, кажется, существуют по причине ...

Ответы [ 4 ]

7 голосов
/ 21 января 2011

В BGL есть не очень хорошо документированный класс признаков, который дает типы дескрипторов вершин и ребер для графа adjacency_list без необходимости знать типы свойств. Он предназначен именно для вашего случая использования. Посмотрите в разделе «Связанные типы» http://www.boost.org/doc/libs/1_45_0/libs/graph/doc/adjacency_list.html и обратите внимание, что есть два определения для vertex_descriptor и edge_descriptor; вы можете использовать версии из adjacency_list_traits в определениях ваших пакетов свойств, не вызывая циклического определения.

0 голосов
/ 20 ноября 2010

Вы включили заголовки циклически.Lane включает графические определения, в том числе lane, графические определения и т. Д. Это является причиной вашей проблемы.

Редактировать: я понял, что это уже упоминалось в OP.Решением этой проблемы является PIMPL.

Редактировать: я бы на самом деле поместил typedef в класс Lane.Это должно решить проблему самым лучшим способом.

0 голосов
/ 20 ноября 2010

@ DeadMG: Я использовал подход, подобный PIMPL, и думаю, что это решило мою проблему.

Так что же я сделал?Я изменил свой класс Lane, чтобы он выглядел следующим образом:

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

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

И класс LaneSide, который практически является косвенным и содержит тип значения, которое я не смог переслать объявить внутри lane.hpp, выглядиттаким образом:

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

Кажется, это обманывает компилятор, как я и собирался.Так что спасибо за подсказку DeadMG.Что мне было интересно: возможно ли хранить объект LaneSide внутри класса Lane не как указатель, а как реальный объект?Я попробовал это сначала, но компилятор пожаловался на конструкцию.И мне также интересно, может ли быть способ избежать дополнительного потребления памяти.Когда мой график станет достаточно большим, это может в конечном итоге стать актуальным.

0 голосов
/ 20 ноября 2010

Я действительно не думаю, что вам нужно что-то особенное в этом коде. Вы должны убедиться, что определения типов, используемых в графе, объявлены (а не только заранее объявлены).

...