2

一部のg++4.xバージョンでこのコードを正しくコンパイルしましたが、バージョン4.6ではエラーが発生してコンパイルが終了します。

/usr/include/boost/pending/property.hpp:35:7: error: ‘boost::property<Tag, T, Base>::m_value’ has incomplete type

このエラーは、graph_typeとedge_infoの型宣言の間のループが原因のようです。

次の数行のコードで問題を特定することができました。ノードのバンドルされたプロパティに依存するタイプを使用して、エッジのプロパティを定義するにはどうすればよいですか?ソリューションは引き続きバンドルされたプロパティを使用する必要があります(多くのコードがこのグラフタイプに依存しているため)。次のコードを修正するにはどうすればよいですか?

#include <iostream>
#include <boost/graph/adjacency_list.hpp>

using namespace std;
using namespace boost;

template<typename map_type>
struct map_computation {
  map_type m;
};

struct vertex_info;
struct edge_info;

typedef adjacency_list<vecS, 
               vecS, 
               bidirectionalS, 
               vertex_info, 
               edge_info> graph_type;

struct position {
  double x, y;
};

struct vertex_info {
  position p;
};

typedef boost::property_map<graph_type, 
                position vertex_info::*>::type position_map_type;

struct edge_info {
  map_computation<position_map_type>* c;
};

int main(int argc, char* argv[])
{
  graph_type g;
  return 0;
}

編集:完全なエラーログは次のようになります。

In file included from /usr/include/boost/graph/graph_traits.hpp:22:0,
                 from /usr/include/boost/graph/adjacency_list.hpp:33,
                 from gtest.cc:2:
/usr/include/boost/pending/property.hpp: In instantiation of ‘boost::property<boost::edge_bundle_t, edge_info, boost::no_property>’:
/usr/include/boost/pending/detail/property.hpp:94:48:   instantiated from ‘boost::detail::build_property_tag_value_alist<boost::property<boost::edge_bundle_t, edge_info, boost::no_property> >’
/usr/include/boost/pending/property.hpp:63:81:   instantiated from ‘boost::property_value<boost::property<boost::edge_bundle_t, edge_info, boost::no_property>, boost::edge_bundle_t>’
/usr/include/boost/graph/properties.hpp:448:63:   instantiated from ‘boost::graph_detail::retagged_bundle<boost::property<boost::edge_bundle_t, edge_info, boost::no_property>, boost::edge_bundle_t>’
/usr/include/boost/graph/properties.hpp:461:64:   instantiated from ‘boost::graph_detail::normal_property<edge_info, boost::edge_bundle_t>’
/usr/include/boost/graph/properties.hpp:473:12:   instantiated from ‘boost::graph_detail::edge_prop<edge_info>’
/usr/include/boost/graph/adjacency_list.hpp:381:70:   instantiated from ‘boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS, vertex_info, edge_info>’
/usr/include/boost/graph/properties.hpp:418:44:   instantiated from ‘boost::property_map<boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS, vertex_info, edge_info>, position vertex_info::*>’
gtest.cc:30:32:   instantiated from here
/usr/include/boost/pending/property.hpp:35:7: error: ‘boost::property<Tag, T, Base>::m_value’ has incomplete type
gtest.cc:13:8: error: forward declaration of ‘struct edge_info’
gtest.cc:33:45: error: template argument 1 is invalid
4

1 に答える 1

1

次のような再帰的な型定義を持つことはできません

struct edge_info;

typedef adjacency_list<..., edge_info> graph_type;

typedef boost::property_map<graph_type, ...>::type position_map_type;

struct edge_info { map_computation<position_map_type>* c; };

たとえば、この質問で述べたように、C++ 標準では §17.4.3.6/2 で次のように述べられています。

特に、次の場合の効果は定義されていません。

__ [..] — テンプレート コンポーネントをインスタンス化するときに、不完全型 (3.9) がテンプレート引数として使用される場合。__ [..]

達成したい内容に応じて (質問から完全には明らかではありません)、次のようなことができる Curiously Recurring Template Pattern (CRTP) を検討することをお勧めします。

template<typename edge>
class some_graph_type 
{ // ... };

class my_edge_type
: 
    public some_graph_type<my_edge_type> 
{ // ... };

したがってedge、それ自体をテンプレート パラメーターとするクラス テンプレートからクラスを派生させることができます。同様に、edgeクラスにメンバー (連結リストと同様) を持たせることはできますが、それ自体edge*の完全な定義を最初に知る必要があるメンバーは持たないことができます。edge

于 2012-06-11T08:36:12.210 に答える