Boost logo

Boost :

Subject: Re: [boost] [Review] TTI
From: Jeffrey Lee Hellrung, Jr. (jeffrey.hellrung_at_[hidden])
Date: 2011-07-27 21:02:04


On Wed, Jul 27, 2011 at 4:23 PM, Edward Diener <eldiener_at_[hidden]>wrote:

> On 7/27/2011 4:14 PM, Jeffrey Lee Hellrung, Jr. wrote:
>
>> On Wed, Jul 27, 2011 at 12:23 PM, Mathias Gaunard<
>> mathias.gaunard_at_[hidden]> wrote:
>>
>> On 07/27/2011 07:52 PM, Jeffrey Lee Hellrung, Jr. wrote:
>>>
>>> I think you missed the convertibility requirement(s).
>>>
>>>>
>>>>>>
>>>>>> TTI needs an exact signature.
>>>>>
>>>>>
>>>>> ...and hence why I had presumed it to be outside of the scope of TTI.
>>>> It
>>>> stills falls within the domain of introspection, though.
>>>>
>>>>
>>> You need SFINAE for expressions to do this.
>>>
>>>
>> You can get a pretty good approximation via something like the following
>> (warning: untested).
>>
>> --------
>> struct yes_type { char _dummy[1]; };
>> struct no_type { char _dummy[2]; };
>>
>> struct dummy_result_t { };
>> yes_type is_dummy_result(dummy_result_**t);
>> no_type is_dummy_result(...);
>>
>> struct base_t
>> { void xxx() { } };
>> template< void (base_t::*)( )>
>> struct has_mem_fn_detector
>> { typedef no_type type; };
>>
>> template< class T>
>> struct derived_t : T, base_t
>> {
>> using T::xxx;
>> dummy_result_t xxx(...) const;
>> };
>>
>> template< class T>
>> typename has_mem_fn_detector< &T::xxx>::type
>> has_mem_fn_test(int);
>> template< class T>
>> yes_type
>> has_mem_fn_test(...);
>> --------
>>
>> First, you determine if T *has* a member function called xxx, regardless
>> of
>> signature, via
>>
>> struct derived2_t : T, base_t { };
>> sizeof( has_mem_fn_test< derived2_t>(0) ) == sizeof( yes_type )
>>
>
> Something is missing here. You have derived2_t as a struct but clearly you
> mean it as a template class since there is no base class T. But if it is a
> template class it can not be passed as a type to has_mem_fn_test.
>

No, I meant it as a plain struct; I'm assuming T is already defined in the
enclosing context, i.e., something like

template< class T >
has_member_function_xxx
{
    struct derived2_t : T, base_t { };
    ... check if T::xxx exists via has_mem_fn_test...
    ... if so, check if T.xxx has a compatible signature ...
};

I am interested in what you may be trying to do here, so that is why I am
> pointing this out.

> Can you correct and explain what you are doing again ? I would like to
> understand the technique for checking convertibility.
>

Let me get a full example put together, then.

> If what you are doing is similar to what Frederick Bron has for type traits
> operators, I will check his code instead.
>

It is similar in spirit, but more of a PITA. BTW, these aren't entirely my
original ideas, but I forget where I pilfered them from :/

> and, if this passes, then you use the expression declval< derived_t<T>
>>
>>> ().xxx(arg0, arg1) (for example) to query, first, whether the type of the
>>>
>> expression is dummy_result_t; then, assuming not, whether the type of the
>> expression has the convertibility properties you desire (for example).
>>
>> It's not perfect, e.g., it breaks when xxx is private or if you want to
>> check nullary member functions (must resort to exact signatures in that
>> case, I think), and I haven't tested what happens when xxx is a static
>> member function. But I don't think any of this is using SFINAE for
>> expressions.
>>
>
- Jeff


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