[graph] porting code from 1.46 to 1.54
Hello boost, I'm trying to move some large code base to use boost 1.54. In some dark corner of it, the following was compiling fine: class Instance; typedef boost::setS OutEdgeList; typedef boost::listS VertexList; struct InstancePropertyTag { typedef boost::vertex_property_tag kind; }; typedef boost::property<InstancePropertyTag, Instance*> InstanceProperty; typedef boost::adjacency_list<OutEdgeList, VertexList, boost::bidirectionalS, InstanceProperty> Graph; typedef boost::property_map<Graph, boost::vertex_index_t>::type IndexGraph; under 1.54, I get 'attempt to form reference to void', but everything was fine under 1.46. I traced it a bit through template expansion, and the problem seems to be that the type for vertex_index_t is not found. The following declaration for InstanceProperty fixes (or hides) the problem: typedef boost::property<InstancePropertyTag, Instance*, boost::property<boost::vertex_index_t, int> > InstanceProperty; Does somebody know if some properties were added by default to graphs before and need to be explicitly added now? I don't find anything in the documentation and all examples I've found seem to imply that one wouldn't need to explicitly add a property declaration of vertex_index_t. Thanks a lot, Maurizio
Hi Maurizio, On Mon, Oct 7, 2013 at 7:04 PM, Maurizio Vitale <mrz.vtl@gmail.com> wrote:
In some dark corner of it, the following was compiling fine:
struct InstancePropertyTag { typedef boost::vertex_property_tag kind; };
under 1.54, I get 'attempt to form reference to void', but everything was
fine under 1.46.
Does somebody know if some properties were added by default to graphs before and need to be explicitly added now?
The internal details of the property implementation have changed quite a bit between version 1.46 and 1.54. I got taken by a similar problem some time ago, and I learned my lesson: Do not rely on the internal details. If things are not documented (i.e., part of the well-defined interface), then you should not rely on it or expect it to remain the same. If you look at the current definition of the BOOST_INSTALL_PROPERTY macro, you see this: #define BOOST_INSTALL_PROPERTY(KIND, NAME) \ template <> struct property_kind<KIND##_##NAME##_t> { \ typedef KIND##_property_tag type; \ } Meaning that you're property-tag should be defined as a partial specialization of the property_kind template. It used to be that the "kind" of the tag was obtained through a straight-forward traits mechanism that just fetched the "kind" nested type within your property-tag class. Now, they added a few layers to that to accommodate "special" tags like "vertex_all_t" or "vertex_bundled_t". The way you defined your custom property-tag may have worked in the old system, but apparently it does not work anymore. The documentation tells you that you should just use the BOOST_DEF_PROPERTY macro for defining new property-tags. That's what you should do. Trying to use the internals directly is not a good idea for portability, because the library implementers cannot be expected to maintain the internals, only the user-facing functionality. So, you should do: namespace boost { BOOST_DEF_PROPERTY(vertex, instance_property) }; typedef boost::vertex_instance_property_t InstancePropertyTag; I hope this solves your problem, Sven Mikael Persson
On Mon, 7 Oct 2013, Maurizio Vitale wrote:
Hello boost,
I'm trying to move some large code base to use boost 1.54.
In some dark corner of it, the following was compiling fine:
class Instance;
typedef boost::setS OutEdgeList; typedef boost::listS VertexList;
struct InstancePropertyTag { typedef boost::vertex_property_tag kind; };
typedef boost::property<InstancePropertyTag, Instance*> InstanceProperty; typedef boost::adjacency_list<OutEdgeList, VertexList, boost::bidirectionalS, InstanceProperty> Graph; typedef boost::property_map<Graph, boost::vertex_index_t>::type IndexGraph;
under 1.54, I get 'attempt to form reference to void', but everything was fine under 1.46.
I traced it a bit through template expansion, and the problem seems to be that the type for vertex_index_t is not found. The following declaration for InstanceProperty fixes (or hides) the problem:
typedef boost::property<InstancePropertyTag, Instance*, boost::property<boost::vertex_index_t, int> > InstanceProperty;
Does somebody know if some properties were added by default to graphs before and need to be explicitly added now? I don't find anything in the documentation and all examples I've found seem to imply that one wouldn't need to explicitly add a property declaration of vertex_index_t.
The vertex_index property is not added to adjacency list graphs with listS as vertex container (and was not before). Did the code ever try to use IndexGraph previously? It is unlikely to have worked. The fix you made is the correct one; be sure to initialize that property if you are going to call algorithms that use it. -- Jeremiah Willcock
Hi Jeremiah, thanks for the suggestion. The code was using IndexGraph. This is code that was put in place way before I joined the company and the authors have long gone. Mikael's suggestion of rewriting the code using only the public interface is probably a good one, but I'll see if I can get this to work by declaring the property explicitly first. Thanks again, Maurizio On Mon, Oct 7, 2013 at 10:39 PM, Jeremiah Willcock <jewillco@crest.iu.edu>wrote:
On Mon, 7 Oct 2013, Maurizio Vitale wrote:
Hello boost,
I'm trying to move some large code base to use boost 1.54.
In some dark corner of it, the following was compiling fine:
class Instance;
typedef boost::setS OutEdgeList; typedef boost::listS VertexList;
struct InstancePropertyTag { typedef boost::vertex_property_tag kind; };
typedef boost::property<**InstancePropertyTag, Instance*> InstanceProperty; typedef boost::adjacency_list<**OutEdgeList, VertexList, boost::bidirectionalS, InstanceProperty> Graph; typedef boost::property_map<Graph, boost::vertex_index_t>::type IndexGraph;
under 1.54, I get 'attempt to form reference to void', but everything was fine under 1.46.
I traced it a bit through template expansion, and the problem seems to be that the type for vertex_index_t is not found. The following declaration for InstanceProperty fixes (or hides) the problem:
typedef boost::property<**InstancePropertyTag, Instance*, boost::property<boost::vertex_**index_t, int> > InstanceProperty;
Does somebody know if some properties were added by default to graphs before and need to be explicitly added now? I don't find anything in the documentation and all examples I've found seem to imply that one wouldn't need to explicitly add a property declaration of vertex_index_t.
The vertex_index property is not added to adjacency list graphs with listS as vertex container (and was not before). Did the code ever try to use IndexGraph previously? It is unlikely to have worked. The fix you made is the correct one; be sure to initialize that property if you are going to call algorithms that use it.
-- Jeremiah Willcock
______________________________**_________________ Unsubscribe & other changes: http://lists.boost.org/** mailman/listinfo.cgi/boost<http://lists.boost.org/mailman/listinfo.cgi/boost>
On Tue, 8 Oct 2013, Maurizio Vitale wrote:
Hi Jeremiah, thanks for the suggestion. The code was using IndexGraph. This is code that was put in place way before I joined the company and the authors have long gone. Mikael's suggestion of rewriting the code using only the public interface is probably a good one, but I'll see if I can get this to work by declaring the property explicitly first.
There is probably also a simpler way to build the graph with the properties you want; use this as the vertex property: boost::property<boost::vertex_index_t, int, Instance*> You should then still be able to use Instance* as a bundled property like you did before, while having the vertex_index property as well. -- Jeremiah Willcock
On Mon, Oct 7, 2013 at 10:39 PM, Jeremiah Willcock <jewillco@crest.iu.edu>wrote:
On Mon, 7 Oct 2013, Maurizio Vitale wrote:
Hello boost,
I'm trying to move some large code base to use boost 1.54.
In some dark corner of it, the following was compiling fine:
class Instance;
typedef boost::setS OutEdgeList; typedef boost::listS VertexList;
struct InstancePropertyTag { typedef boost::vertex_property_tag kind; };
typedef boost::property<**InstancePropertyTag, Instance*> InstanceProperty; typedef boost::adjacency_list<**OutEdgeList, VertexList, boost::bidirectionalS, InstanceProperty> Graph; typedef boost::property_map<Graph, boost::vertex_index_t>::type IndexGraph;
under 1.54, I get 'attempt to form reference to void', but everything was fine under 1.46.
I traced it a bit through template expansion, and the problem seems to be that the type for vertex_index_t is not found. The following declaration for InstanceProperty fixes (or hides) the problem:
typedef boost::property<**InstancePropertyTag, Instance*, boost::property<boost::vertex_**index_t, int> > InstanceProperty;
Does somebody know if some properties were added by default to graphs before and need to be explicitly added now? I don't find anything in the documentation and all examples I've found seem to imply that one wouldn't need to explicitly add a property declaration of vertex_index_t.
The vertex_index property is not added to adjacency list graphs with listS as vertex container (and was not before). Did the code ever try to use IndexGraph previously? It is unlikely to have worked. The fix you made is the correct one; be sure to initialize that property if you are going to call algorithms that use it.
-- Jeremiah Willcock
______________________________**_________________ Unsubscribe & other changes: http://lists.boost.org/** mailman/listinfo.cgi/boost<http://lists.boost.org/mailman/listinfo.cgi/boost>
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
participants (3)
-
Jeremiah Willcock
-
Maurizio Vitale
-
Mikael Persson