0

循環テンプレート参照について問題があります。次のように、クラス ノードとクラス エッジを使用してツリーを作成します。

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

クラスの構造を再定義するにはどうすればよいですか?

4

2 に答える 2

3

これが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 ++テンプレートメタプログラミングは関数型言語です。使用できる前方宣言なしで再帰構造を記述するために、関数型プログラミングからさまざまな手法があります。

ある種の固定小数点コンビネータが機能するかもしれないと私は確信していますが、その方法を理解することは私を超えています。:)

于 2013-03-11T02:45:33.047 に答える
0

テンプレートを使用する必要がある理由を理解する必要があります。たとえば、エッジでデータを動的にしたい場合は、次を使用できます。

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

同様に、ノードで異なるデータが必要な場合。ただし、一般的には、テンプレートの理由を事前に把握しておくことをお勧めします。私は過度にテンプレート化された製品コードを見てきましたが、それはかなり保守不可能です。

于 2013-03-11T02:09:38.413 に答える