Как я могу использовать шаблонные определения типа, которые являются _in_ классом, из-за пределов класса (например, другим классом), относительно boost :: graph - PullRequest
1 голос
/ 12 февраля 2010

Я нашел очень полезный ответ о том, как создавать шаблонные графы, используя boost :: graph, в разделе Изменение свойств вершин в Boost :: Graph

Для меня это очень удобно, если я делаю всю работу над графиком в самом классе Graph.

Однако может потребоваться доступ к информации извне, например, Можно захотеть реализовать класс Printer, который принимает объект Graph и распечатывает всю сохраненную информацию.

В этом случае может быть удобно получить доступ ко всем вершинам (например, с помощью итератора вершин). К сожалению, это не сработает, так как весь typedef выполняется в классе Graph, и эта информация недоступна извне, поэтому класс Printer не будет знать, что такое итератор вершин и т. Д.

Как я мог решить эту проблему и при этом сохранить шаблонный аспект?

Спасибо.

Ответы [ 3 ]

0 голосов
/ 12 февраля 2010

К сожалению, это не сработает, так как все typedef выполняется в классе Graph и эта информация недоступна извне

Я не совсем слежу за тем, что все typedef общедоступны, поэтому они очень хорошо доступны извне. Просто используйте typename при доступе к зависимому имени:

typename Graph<TProp, TEdge>::vertex_iterator i;
0 голосов
/ 12 февраля 2010

Ваш вопрос меня немного смущает, но я думаю, вы ищете что-то вроде этого:

// console was chosen just to make the example simple, but 
// it can be more generic easily
template <typename vertex_t>
class ConsolePrinter {
public:
    template <typename iter_t>
    void print(iter_t vbegin, iter_t vend) const {
       copy(vbegin, vend, std::ostream_iterator<vertex_t>(std::cout, "\r\n"));
    }
};

Тогда, следуя приведенному вами примеру, вы получите что-то вроде этого:

typedef Graph<VertexProperties, EdgeProperties> MyGraph;
MyGraph g;
MyGraph::vertex_range_t vertices_range = g.getVertices(); 
ConsolePrinter<MyGraph::Vertex> printer;   
printer.print(vertices_range.first,vertices_range.second);

Как уже говорил Конрад и другие в этой теме, у вас нет проблем с доступом к итератору и другим определениям типов из этого класса, и вы можете сделать свое решение очень универсальным. Кстати, решение для печати, которое вы выберете, налагает определенные ожидания (в моем случае, тип вершины должен работать с operator<< из ostream), но это может быть сделано без потери общего аспекта решения.

0 голосов
/ 12 февраля 2010

Но определения типов общедоступны, поэтому вы можете получить к ним доступ извне:

template<typename T>
class A
{
public:
    typedef T type;
    typedef unsigned data;
};

Теперь это следующее:

A<int>::type // int
A<int>::data // unsigned

Будьте осторожны, если Т не указан

template<typename T>
void func( A<T>& a )
{
    typename A<T>::type // T
    typename A<T>::data // unsigned
}
...