Boost logo

Boost :

Subject: Re: [boost] [BGL] Visual Studio 12 finish_edge() failure, general BOOST_TTI_HAS_MEMBER_FUNCTION failure?
From: Edward Diener (eldiener_at_[hidden])
Date: 2014-04-10 08:35:13


On 4/10/2014 2:18 AM, Jeremiah Willcock wrote:
>
>
> On Tue, Apr 1, 2014 1:12 PM PDT Michael Behrns-Miller wrote:
>
>> 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 <typename E, typename G, typename Vis>
>>>>> 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 <typename E, typename G, typename Vis>
>>>>> static void call_finish_edge(Vis&, const E&, const G&) {}
>>>>> };
>>>>>
>>>>> template <typename E, typename G, typename Vis>
>>>>> void call_finish_edge(Vis& vis, const E& e, const G& g) { // Only
>>>>> call if method exists
>>>>> do_call_finish_edge<has_member_function_finish_edge<Vis,
>>>>> void>::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<has_member_function_finish_edge<Vis,
>>>> void>::value>::call_finish_edge(vis, e, g);
>>>>
>>>> to...
>>>>
>>>> do_call_finish_edge<has_member_function_finish_edge<void Vis::* (const
>>>> E&,const G&)>::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.
>
> I wanted a way to test for equivalent signatures for the finish_edge member (copy vs. const ref, for example). I probably believed/saw somewhere that the syntax I used would do that. Is there a way to get a general "call ability" test for a member function using TTI?

If by general "call ability" you mean a name with any signature, that is
not currently in TTI. If you know of a way to do this I would be glad to
incorporate it in TTI.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk