-->

圆形模板参考结构(Circular template reference structure)

2019-11-01 18:34发布

我有一个圆形模板参考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..

我怎样才能重新定义类的结构?

Answer 1:

这是一种方法:

#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 ++模板元编程是一个功能性的语言 - 有从功能编程,以便描述递归结构没有可使用的前向声明的各种技术。

我打赌某种可能的工作的不动点组合子,却是超越我要弄清楚如何。 :)



Answer 2:

你需要弄清楚为什么你需要使用模板的原因。 例如,如果你想在一个边缘的动态数据,你可以使用:

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

同样,如果你想有一个在你的节点不同的数据。 但一般最好是事先弄清楚了模板的原因。 我已经看过过于模板化生产代码,这是相当难以维护。



文章来源: Circular template reference structure