我有一个圆形模板参考ploblem。 我想用类节点和边缘类如下做出树;
template <typename EdgeT>
class node
{
public:
std::vector<EdgeT> edge_out;
std::vector<EdgeT> edge_in;
};
template <typename NodeT>
class edge
{
public:
NodeT* src;
NodeT* dst;
int weight;
};
template <typename NodeT, typename EdgeT>
class graph
{
public:
std::vector<NodeT> nodes;
};
我发现我不能宣布图形类ex:
graph< node, edge > g; // <--- this cannot be solved
graph< node< edge <node.....>, edge< node< edge>> > //it makes infinity declaration..
我怎样才能重新定义类的结构?
这是一种方法:
#include <vector>
template<template<typename NodeT,typename T>class EdgeT, typename T=double>
struct Node {
typedef Node<EdgeT,T> self_type;
typedef EdgeT<self_type, T> edge_type;
std::vector<edge_type> edge_out;
std::vector<edge_type> edge_in;
T data;
};
template<typename NodeT,typename T>
struct Edge {
typedef NodeT node_type;
node_type* src;
node_type* dst;
int weight;
};
template<typename NodeT, typename EdgeT=typename NodeT::edge_type>
struct graph {
typedef NodeT node_type;
typedef EdgeT edge_type;
std::vector<NodeT> nodes;
};
int main() {
typedef graph< Node<Edge> > graph_type;
graph_type my_graph;
my_graph.nodes.push_back( graph_type::node_type() );
my_graph.nodes.push_back( graph_type::node_type() );
my_graph.nodes.front().edge_out.push_back( {&my_graph.nodes[0], &my_graph.nodes[1], 1} );
my_graph.nodes.back().edge_in.push_back( {&my_graph.nodes[0], &my_graph.nodes[1], 1} );
}
对于另一种方法,你可以看看是如何boost::variant
处理递归变种。
解决这个另一种方式是比较正规的。 C ++模板元编程是一个功能性的语言 - 有从功能编程,以便描述递归结构没有可使用的前向声明的各种技术。
我打赌某种可能的工作的不动点组合子,却是超越我要弄清楚如何。 :)
你需要弄清楚为什么你需要使用模板的原因。 例如,如果你想在一个边缘的动态数据,你可以使用:
//foward declaration
template <typename T>
class node
{
std::vector<Edge<T> > edge_out;
std::vector<Edge<T> > edge_in;
}
template <typename T>
class edge
{
Node<T>* src;
Node<T>* dst;
T weight
}
template <typename T>
class graph
{
std::vector<Node<T> > nodes;
}
同样,如果你想有一个在你的节点不同的数据。 但一般最好是事先弄清楚了模板的原因。 我已经看过过于模板化生产代码,这是相当难以维护。