[BGL] Visual Studio 12 finish_edge() failure, general BOOST_TTI_HAS_MEMBER_FUNCTION failure?
Hello boost!
In the BGL, finish_edge() is a visitor function of DFS, but it is
optional. It is made optional via BOOST_TTI_HAS_MEMBER_FUNCTION. Here's
how BGL defines it:
-------------
BOOST_TTI_HAS_MEMBER_FUNCTION(finish_edge)
template <bool IsCallable> struct do_call_finish_edge {
template
On 3/31/2014 1:27 PM, Michael Behrns-Miller wrote:
Hello boost!
In the BGL, finish_edge() is a visitor function of DFS, but it is optional. It is made optional via BOOST_TTI_HAS_MEMBER_FUNCTION. Here's how BGL defines it:
-------------
BOOST_TTI_HAS_MEMBER_FUNCTION(finish_edge)
template <bool IsCallable> struct do_call_finish_edge { template
static void call_finish_edge(Vis& vis, const E& e, const G& g) { vis.finish_edge(e, g); } }; template <> struct do_call_finish_edge<false> { template
static void call_finish_edge(Vis&, const E&, const G&) {} }; template
void call_finish_edge(Vis& vis, const E& e, const G& g) { // Only call if method exists do_call_finish_edge ::value>::call_finish_edge(vis, e, g); }
The invocation of has_member_function_finish_edge has to match the member function signature which you are invoking. If the member function signature for finish_edge is: void finish_edge(const E&, const G&); then your invocation for do_call_finish_edge must be: do_call_finish_edge < has_member_function_finish_edge < Vis, void, boost::mpl::vector < const E&, const G& > > ::value
::call_finish_edge(vis, e, g);
or do_call_finish_edge < has_member_function_finish_edge < void Vis::* (const E&,const G&) > ::value
::call_finish_edge(vis, e, g);
On 3/31/2014 6:30 PM, Edward Diener wrote:
On 3/31/2014 1:27 PM, Michael Behrns-Miller wrote:
... Here's how BGL defines it:
-------------
BOOST_TTI_HAS_MEMBER_FUNCTION(finish_edge)
template <bool IsCallable> struct do_call_finish_edge { template
static void call_finish_edge(Vis& vis, const E& e, const G& g) { vis.finish_edge(e, g); } }; template <> struct do_call_finish_edge<false> { template
static void call_finish_edge(Vis&, const E&, const G&) {} }; template
void call_finish_edge(Vis& vis, const E& e, const G& g) { // Only call if method exists do_call_finish_edge ::value>::call_finish_edge(vis, e, g); } The invocation of has_member_function_finish_edge has to match the member function signature which you are invoking. If the member function signature for finish_edge is:
void finish_edge(const E&, const G&);
then your invocation for do_call_finish_edge must be:
do_call_finish_edge < has_member_function_finish_edge < Vis, void, boost::mpl::vector < const E&, const G& > > ::value
::call_finish_edge(vis, e, g);
or
do_call_finish_edge < has_member_function_finish_edge < void Vis::* (const E&,const G&) > ::value
::call_finish_edge(vis, e, g);
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Thank you Edward.
The instantiation code was not mine, that is what is done by the BGL, here:
boost\graph\depth_first_search.hpp
The instantiation code does not seem to match your recommendation. This
simple DFS test fails:
https://svn.boost.org/trac/boost/attachment/ticket/9770/test.cc
So it sounds like BGL needs some patching to match your format. It
should change from...
do_call_finish_edge
On 4/1/2014 4:40 AM, Michael Behrns-Miller wrote:
On 3/31/2014 6:30 PM, Edward Diener wrote:
On 3/31/2014 1:27 PM, Michael Behrns-Miller wrote:
... Here's how BGL defines it:
-------------
BOOST_TTI_HAS_MEMBER_FUNCTION(finish_edge)
template <bool IsCallable> struct do_call_finish_edge { template
static void call_finish_edge(Vis& vis, const E& e, const G& g) { vis.finish_edge(e, g); } }; template <> struct do_call_finish_edge<false> { template
static void call_finish_edge(Vis&, const E&, const G&) {} }; template
void call_finish_edge(Vis& vis, const E& e, const G& g) { // Only call if method exists do_call_finish_edge ::value>::call_finish_edge(vis, e, g); } The invocation of has_member_function_finish_edge has to match the member function signature which you are invoking. If the member function signature for finish_edge is:
void finish_edge(const E&, const G&);
then your invocation for do_call_finish_edge must be:
do_call_finish_edge < has_member_function_finish_edge < Vis, void, boost::mpl::vector < const E&, const G& > > ::value
::call_finish_edge(vis, e, g);
or
do_call_finish_edge < has_member_function_finish_edge < void Vis::* (const E&,const G&) > ::value
::call_finish_edge(vis, e, g);
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Thank you Edward.
The instantiation code was not mine, that is what is done by the BGL, here:
boost\graph\depth_first_search.hpp
The instantiation code does not seem to match your recommendation. This simple DFS test fails:
https://svn.boost.org/trac/boost/attachment/ticket/9770/test.cc
So it sounds like BGL needs some patching to match your format. It should change from...
do_call_finish_edge
::value>::call_finish_edge(vis, e, g); to...
do_call_finish_edge
::value>::call_finish_edge(vis, e, g); Does that sound correct?
On the newer code, Visual Studio 12 gives me: boost_1_55_0/boost/graph/depth_first_search.hpp(86): error C2182: 'abstract declarator' : illegal use of type 'void'
On 4/1/2014 4:50 AM, Michael Behrns-Miller wrote:
On 4/1/2014 4:40 AM, Michael Behrns-Miller wrote:
On 3/31/2014 6:30 PM, Edward Diener wrote:
On 3/31/2014 1:27 PM, Michael Behrns-Miller wrote:
... Here's how BGL defines it:
-------------
BOOST_TTI_HAS_MEMBER_FUNCTION(finish_edge)
template <bool IsCallable> struct do_call_finish_edge { template
static void call_finish_edge(Vis& vis, const E& e, const G& g) { vis.finish_edge(e, g); } }; template <> struct do_call_finish_edge<false> { template
static void call_finish_edge(Vis&, const E&, const G&) {} }; template
void call_finish_edge(Vis& vis, const E& e, const G& g) { // Only call if method exists do_call_finish_edge ::value>::call_finish_edge(vis, e, g); } The invocation of has_member_function_finish_edge has to match the member function signature which you are invoking. If the member function signature for finish_edge is:
void finish_edge(const E&, const G&);
then your invocation for do_call_finish_edge must be:
do_call_finish_edge < has_member_function_finish_edge < Vis, void, boost::mpl::vector < const E&, const G& > > ::value
::call_finish_edge(vis, e, g);
or
do_call_finish_edge < has_member_function_finish_edge < void Vis::* (const E&,const G&) > ::value
::call_finish_edge(vis, e, g);
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Thank you Edward.
The instantiation code was not mine, that is what is done by the BGL, here:
boost\graph\depth_first_search.hpp
The instantiation code does not seem to match your recommendation. This simple DFS test fails:
https://svn.boost.org/trac/boost/attachment/ticket/9770/test.cc
So it sounds like BGL needs some patching to match your format. It should change from...
do_call_finish_edge
::value>::call_finish_edge(vis, e, g); to...
do_call_finish_edge
::value>::call_finish_edge(vis, e, g); Does that sound correct?
On the newer code, Visual Studio 12 gives me:
boost_1_55_0/boost/graph/depth_first_search.hpp(86): error C2182: 'abstract declarator' : illegal use of type 'void'
I am the developer for TTI. In your test case the actual VIZ struct has templated member functions, so I do not think has_member_function will find your templated functions. TTI is a compile-time mechanism for producing compile-time code. But even if it does not find the member functions at compile-time TTI should not produce a compile-time error so I definitely want to look at this situation. As to why Visual Studio 12 gives that error I need to be able to reproduce your compile steps. I am an absolute novice with the Boost graph library. I think I need to build the library first, then run your test against it. Jeremiah Willcock produced the changes in graph using TTI so he may have had a very good reason for using the original has_member_function signature, although it looks wrong to me on purely a TTI basis. Hopefully he will chime in on his change.
On 4/1/2014 8:45 AM, Edward Diener wrote:
On 4/1/2014 4:50 AM, Michael Behrns-Miller wrote:
On 4/1/2014 4:40 AM, Michael Behrns-Miller wrote:
On 3/31/2014 6:30 PM, Edward Diener wrote:
On 3/31/2014 1:27 PM, Michael Behrns-Miller wrote:
... Here's how BGL defines it:
-------------
BOOST_TTI_HAS_MEMBER_FUNCTION(finish_edge)
template <bool IsCallable> struct do_call_finish_edge { template
static void call_finish_edge(Vis& vis, const E& e, const G& g) { vis.finish_edge(e, g); } }; template <> struct do_call_finish_edge<false> { template
static void call_finish_edge(Vis&, const E&, const G&) {} }; template
void call_finish_edge(Vis& vis, const E& e, const G& g) { // Only call if method exists do_call_finish_edge ::value>::call_finish_edge(vis, e, g); } The invocation of has_member_function_finish_edge has to match the member function signature which you are invoking. If the member function signature for finish_edge is:
void finish_edge(const E&, const G&);
then your invocation for do_call_finish_edge must be:
do_call_finish_edge < has_member_function_finish_edge < Vis, void, boost::mpl::vector < const E&, const G& > > ::value
::call_finish_edge(vis, e, g);
or
do_call_finish_edge < has_member_function_finish_edge < void Vis::* (const E&,const G&) > ::value
::call_finish_edge(vis, e, g);
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Thank you Edward.
The instantiation code was not mine, that is what is done by the BGL, here:
boost\graph\depth_first_search.hpp
The instantiation code does not seem to match your recommendation. This simple DFS test fails:
https://svn.boost.org/trac/boost/attachment/ticket/9770/test.cc
So it sounds like BGL needs some patching to match your format. It should change from...
do_call_finish_edge
::value>::call_finish_edge(vis, e, g); to...
do_call_finish_edge
::value>::call_finish_edge(vis, e, g); Does that sound correct?
On the newer code, Visual Studio 12 gives me:
boost_1_55_0/boost/graph/depth_first_search.hpp(86): error C2182: 'abstract declarator' : illegal use of type 'void'
I am the developer for TTI. In your test case the actual VIZ struct has templated member functions, so I do not think has_member_function will find your templated functions. TTI is a compile-time mechanism for producing compile-time code. But even if it does not find the member functions at compile-time TTI should not produce a compile-time error so I definitely want to look at this situation.
As to why Visual Studio 12 gives that error I need to be able to reproduce your compile steps. I am an absolute novice with the Boost graph library. I think I need to build the library first, then run your test against it.
Jeremiah Willcock produced the changes in graph using TTI so he may have had a very good reason for using the original has_member_function signature, although it looks wrong to me on purely a TTI basis. Hopefully he will chime in on his change.
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Thanks Edward, appreciate the feedback, I'll be monitoring. In the meantime my workaround of making finish_edge() non-optional is working for me. But of course I'd prefer not to have to change boost code before using. :-) Sure appreciate all you guys do to develop and maintain the libraries, boost is just fantastic.
participants (2)
-
Edward Diener
-
Michael Behrns-Miller