我正在尝试开发2个类, Node 和 Connection ,但我没有C ++或C ++模板的经验。
节点包含连接列表,Connection包含2个节点。 所以我假设一个节点有一个模板参数,它指定列表中的连接类型,并且连接有一个模板参数,用于指定它包含哪种节点。
如何在C ++中强制该节点包含泛型类型的连接,但这些连接是否包含Node类的节点? Connection类的相同问题。我希望有一个节点类型的泛型参数,但这些通用节点必须包含一个连接类连接的列表。
我尝试了几件事,这就是我现在所拥有的:
template <template <template <class Conn> class Node> class Conn>
class Node {
};
有人可以帮助我吗?
提前致谢,
杰夫
答案 0 :(得分:3)
假设您需要不同类型的节点,但是Connections只是两个节点之间的链接(也就是说,您不需要对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的模式。
还有其他攻击方式 - 您能否提供有关特定问题域的更多信息?
编辑以显示侵入性与非侵入式技术
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;
}