Boost logo

Boost :

Subject: Re: [boost] [introspection] Status
From: Jeffrey Hellrung (jhellrung_at_[hidden])
Date: 2009-07-22 12:46:38


Richard Hazlewood wrote:
> I've actually been looking for a way to check for: does (or, perhaps can)
> template function exist in type.
>
> I've been experimenting with modifying your macro, so that the signature
> becomes a template argument. E.g. so code such as:
>
> template <typename R, typename X>
> void foo()
> {
> bool const has = has_non_const_member_function_bar<X, R (*)()>::value;
> ...
> }
>
> struct X
> {
> template <typename T>
> T bar();
> };
>
> foo<int, X>();
>
> Could be made to work.
>
> Trying:
>
> 1] #define BOOST_HAS_NON_CONST_MEMBER_FUNCTION(Name,Sig) \
> 2] namespace boost \
> 3] { \
> 4] namespace introspection \
> 5] { \
> 6] template<class T, class F = Sig> \
> 7] struct BOOST_PP_CAT(has_non_const_member_function_,Name) \
> 8] { \
> 9] typedef char NotFound; \
> A] struct Found { char x[2]; }; \
> B] \
> C] template< typename build_member_type<T,F>::type \
> D] > struct member {}; \
> E] \
> F] template<class X> static Found test(member<&X::Name>*); \
> G] template<class X> static NotFound test( ... ); \
> H] \
> I] static const bool value = (sizeof(Found) == sizeof(test<T>(0))); \
> J] typedef mpl::bool_<value> type; \
> K] }; \
> L] } \
> M] } \
> /**/
>
> However, it doesn't appear to work (at least in VC71). It looks like the
> sizeof trick is not capable of stamping out the template function.
>
> Do you know if this can be achieved?
>
> Note: Lines [C-D, F] were modified from:
>
> template< class X \
> , typename build_const_member_type<X,F>::type \
> > struct member {};
>
> template<class X> static Found test(X, member<&X::Name>*); \
>
> Because VC71 would not compile it that way when Sig was a template arg (F).
> [shrug].
>
> This didn't seem to affect the original behaviour, was there a reason for it?
>

I've been able to get a has_mem_fn-type trait to work on MSVC 8 and 9 by
using the technique in the Adobe Move library's class_has_move_assign,

http://stlab.adobe.com/move_8hpp_source.html

Your lines [C-F] would look slightly different, roughly like

template< typename signature< T0, ..., TN >::type > struct sfinae {
typedef yes_type type; };
template< class U > static typename sfinae< &U:: name >::type test(int);
template< class U > static no_type test(...);

I don't know if this is any better for MSVC 7, though, but you can try :/

- Jeff


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