C++模板问题

发布于 2024-11-04 18:12:55 字数 501 浏览 0 评论 0原文

我正在尝试开发 2 个类,NodeConnection,但我没有 C++ 或 C++ 模板的经验。

Node 包含一个连接列表,一个 Connection 包含 2 个节点。 因此,我假设节点有一个模板参数,用于指定列表中的连接类型,并且连接有一个模板参数,用于指定它包含哪种类型的节点。

如何在 C++ 中强制该节点包含泛型类型的连接,但这些连接包含 Node 类的节点? Connection 类有同样的问题。我想要一个节点类型的通用参数,但这些通用节点必须包含一个包含 Connection 类连接的列表。

我已经尝试了几件事,这就是我目前所拥有的:

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

有人可以帮助我吗?

预先感谢,

杰夫

I'm trying to develop 2 classes, Node and Connection, but I don't have experience in C++ or C++ templates.

The Node contains a list of connections and a Connection contains 2 nodes.
So I suppose that a node has a template parameter that specifies which type of connections are in the list and that a connection has a template parameter that specifies which kind of nodes it contains.

How can I enforce in C++ that the node contains connections of a generic type but that these connections contain nodes of the class Node? The same question for the Connection class. I want to have a generic parameter for the type of the nodes, but these generic nodes must contain a list with connections of the Connection class.

I've tried several things, this is what I have at the moment:

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

Can someone help me?

Thanks in advance,

Jef

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

千纸鹤 2024-11-11 18:12:55

假设您想要不同类型的节点,但连接只是两个节点之间的链接(也就是说,您不需要对连接进行任何专门化),那么您可以执行以下操作:

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

Assuming that you want different types of Nodes, but that Connections are nothing but a link between two Nodes (that is, that you don't need to do any specialisation on the Connections) then you could do something like:

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

This is a pattern called the curiously recurring template pattern.

There are other ways of attacking this - can you give more info on your specific problem domain?

EDIT to show intrusive vs non-intrusive techniques

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文