【问题标题】:Incomplete type error in BGL when using bundled properties使用捆绑属性时 BGL 中的不完整类型错误
【发布时间】:2012-06-10 18:54:14
【问题描述】:

我在某些 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

【问题讨论】:

  • 错误是否说 with Tag = ..., T = ..., Base = ...
  • @K-ballo 我已在问题正文中包含完整的错误报告。谢谢。

标签: c++ boost undefined-behavior boost-graph


【解决方案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; };

正如在例如this question,C++ 标准在 §17.4.3.6/2 中说,

特别是在以下情况下效果是不确定的:

__ [..] — 如果在实例化模板组件时将不完整类型 (3.9) 用作模板参数。 __ [..]

根据您想要完成的任务(您的问题并不完全清楚),您可能需要考虑奇怪重复的模板模式 (CRTP),您可以在其中执行以下操作:

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

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

因此,您可以让edge 类派生自类模板,并将其自身作为模板参数。同样,您可以让edge 类有一个edge* 成员(类似于链接列表),但不是您需要首先了解edge 本身的完整定义的成员。

【讨论】:

  • 谢谢,我以为错误是我的,而不是编译器的。尽管如此,我想通过对使用 graph_type 的代码的最小更改来解决编译错误。 (顺便说一句:我无法更改 boost::graph 类型(它是一个 boost 类型),所以我不明白 CRTP 对我的情况有何帮助,请解释一下。
  • @baol 正如我所解释的,如果您只有 edge* 作为成员类型,它会起作用。但如果您有一个以edge 作为模板参数的成员指针,则不会。
  • @baol 你刚刚撤销了“接受”状态吗?请让我知道如何改进答案。
  • @TemplateTex 您详细描述了问题,但没有提供解决方案。如果您需要更多上下文,请参阅 boost 图形库文档。
猜你喜欢
  • 1970-01-01
  • 2016-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多