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-01 08:45:55


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.


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