Проблема с C ++ шаблонами - PullRequest
3 голосов
/ 04 мая 2011

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

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

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

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

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

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

Заранее спасибо,

Джеф

1 Ответ

3 голосов
/ 04 мая 2011

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

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.
}

Это шаблон, называемый любопытно повторяющимся шаблоном .

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

РЕДАКТИРОВАТЬ, чтобы показать навязчивые и неинтрузивные методы

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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...