2011-05-04 7 views
3

Я пытаюсь разработать 2 класса, Узел и Соединение, но у меня нет опыта в шаблонах на C++ или C++.Проблема с C++ шаблонами

Узел содержит список соединений и соединение содержит 2 узла. Итак, я полагаю, что узел имеет параметр шаблона, который указывает, какой тип соединений находится в списке, и что у соединения есть параметр шаблона, который указывает, какие именно узлы он содержит.

Как можно принудительно выполнить на C++, что узел содержит соединения общего типа, но что эти соединения содержат узлы класса Node? Тот же вопрос для класса Connection. Я хочу иметь общий параметр для типа узлов, но эти общие узлы должны содержать список с соединениями класса Connection.

Я попробовал несколько вещей, это то, что у меня есть на данный момент:

template <template <template <class Conn> class Node> class Conn> 
class Node { 
}; 

Может кто-нибудь мне помочь?

Спасибо заранее,

Джеф

+3

Почему использование готовых шаблонов? –

ответ

3

Предполагая, что вы хотите различные типы узлов, но соединения не являются ничем иным, как связь между двумя узлами (то есть, что вам не нужно делать какие-либо специализация на Connections), то вы могли бы сделать что-то вроде:

template <class Node> 
class Connection 
{ 
    Node& node1; 
    Node& node2; 
}; 

template <class Node> 
class NodeBase 
{ 
    std::list< Connection<Node> > connections; 
}; 

// example concrete node 
class MassNode : public NodeBase<MassNode> 
{ 
    // stuff that makes a mass node more than just a node. 
} 

Это шаблон называется curiously recurring template pattern.

Есть другие способы атаковать это - можете ли вы дать больше информации о своей конкретной проблемной области?

EDIT, чтобы показать навязчивым против неинтрузивных методов

namespace intrusive 
{ 
    template <class node> 
    class directedConnection 
    { 
     node& From; 
     node& To; 
    }; 

    template <class node> 
    class directedGraphNode 
    { 
    private: 
     std::set< directedConnection<node>* > OutgoingConnections; 
     std::set< directedConnection<node>* > IncomingConnections; 
    }; 

    // sample concrete class. Note that it is a graph node AND it contains the node data. 
    class bayesianNetworkNode : public directedGraphNode<bayesianNetworkNode> 
    { 
    public: 
     double Probabilities[16]; 
    }; 

    bayesianNetworkNode B1, B2, B3; 
} 

namespace non_intrusive 
{ 
    template <class T> 
    class undirectedGraphNode; 

    template <class T> 
    class undirectedConnection 
    { 
     undirectedGraphNode<typename T>& Node1; 
     undirectedGraphNode<typename T>& Node2; 
    }; 

    template <class T> 
    class undirectedGraphNode 
    { 
    private: 
     std::set< undirectedConnection<T>* > Connections; 
     T Value; 
    public: 
     T& operator *() { return Value; } 
     T* operator ->() { return &Value; } 
    }; 

    // sample concrete class. Note that this class contains the node data, but is NOT actually a graph node itself. 
    // It is "pointed to" by a node in the same way that an STL iterator "points to" a collection item. 
    class markovNetworkNode 
    { 
    public: 
     std::set<formula> Formulae; 
    }; 

    undirectedGraphNode<markovNetworkNode> M1, M2, M3; 
} 
+0

Спасибо! Я хочу моделировать сети Байеса и Маркова. Таким образом, конкретный узел может быть случайной величиной, например, и соединение может быть либо направленным, либо ненаправленным. Поэтому мне также нужны специализации в классе Connection ... Как я могу это исправить? – hermi

+0

На моем пути - вернемся позже с помощью двух методов - одного навязчивого (как указано выше кода), а другого нет. –

+0

+1 Хороший ответ. Чистый, простой и выполняет эту работу. Также полностью общий. – ralphtheninja

Смежные вопросы