Проблема с шаблонами C

#c #templates

#c #шаблоны

Вопрос:

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

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

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

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

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

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

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

Jef

Ответ №1:

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

 template <class Node>
class Connection
{
    Nodeamp; node1;
    Nodeamp; 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
    {
        nodeamp; From;
        nodeamp; 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>amp; Node1;
        undirectedGraphNode<typename T>amp; Node2;
    };

    template <class T>
    class undirectedGraphNode
    {
    private:
        std::set< undirectedConnection<T>* > Connections;
        T Value;
    public:
        Tamp; operator * () { return Value; }
        T* operator -> () { return amp;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;
}
  

Комментарии:

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

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

3. 1 хороший ответ. Чистый, простой и выполняет свою работу. Также полностью универсальный.

4. Отредактировано, чтобы показать примеры направленной и неориентированной сети. И чтобы показать разницу между навязчивым (каждый узел содержит свои данные бизнес-уровня, а также участвует в графике) и ненавязчивым (класс, написанный для хранения бизнес-данных каждого узла, ничего не знает о том факте, который содержится в графике.). Последний метод используется многими универсальными контейнерами, в частности STL.