Boost logo

Boost :

Subject: Re: [boost] [Review] TTI
From: John Bytheway (jbytheway+boost_at_[hidden])
Date: 2011-07-28 17:49:23


On 28/07/11 19:07, Jeffrey Lee Hellrung, Jr. wrote:
<snip>
>> Maybe a generic method for any number of types would be possible through
>> using Boost function types.
>
> The way to go, I think, is BOOST_PP_ITERATE (since you have to construct the
> actual call expression declval<T>().xxx(declval<T0>(), declval<T1>(), ...,
> declval<T[N-1]>()))...which implies that you'll have to have a
>
> #define BOOST_TTI_PARAM_1 foo
> #define BOOST_TTI_PARAM_2 bar
> #include BOOST_TTI_HAS_MEMBER_FUNCTION_THINGY()
>
> interface rather than a metafunction-generating macro interface. I guess
> you can use BOOST_PP_REPEAT but it could make the implementation unwieldy
> and make it potentially very difficult to track down usage errors :/
> Variadic templates *might* work here, but I'm really not sure.

Yes, variadic templates make it easy; e.g. this alteration to the end of
your code works for me with clang++:

template< class T, class Result, class... Args >
struct has_mem_fn_helper< T, Result ( Args... ) >
{
    static const bool value =
        (sizeof( is_dummy_result_t(
           declval< derived_t<T>>().xxx(declval<Args>()...)) ) ==
         sizeof( no_type ))
     && (sizeof( is_convertible< Result >::apply(
           declval< derived_t<T>>().xxx(declval<Args>()...)) ) ==
          sizeof( yes_type ));
    typedef has_mem_fn_helper type;
};

struct X
{ };

struct Y
{ int xxx(int); };

struct Z
{ int xxx(int, int); };

int main(int /*argc*/, char* /*argv*/[])
{
    BOOST_STATIC_ASSERT(!(has_mem_fn< X >::value));
    BOOST_STATIC_ASSERT( (has_mem_fn< Y >::value));
    BOOST_STATIC_ASSERT( (has_mem_fn< Y, int ( int ) >::value));
    BOOST_STATIC_ASSERT( (has_mem_fn< Y, long ( short ) >::value));
    BOOST_STATIC_ASSERT(!(has_mem_fn< Y, int ( void* ) >::value));
    BOOST_STATIC_ASSERT(!(has_mem_fn< Y, void* ( int ) >::value));
    BOOST_STATIC_ASSERT(!(has_mem_fn< Z, int ( int ) >::value));
    BOOST_STATIC_ASSERT(!(has_mem_fn< Z, int ( void* ) >::value));
    BOOST_STATIC_ASSERT( (has_mem_fn< Z, int ( int, long ) >::value));
    BOOST_STATIC_ASSERT(!(has_mem_fn< Z, int ( void*, int ) >::value));
    return 0;
}

John Bytheway


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