我在一些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
答案 0 :(得分: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
本身的完整定义的成员。