
On Thu, Jul 28, 2011 at 2:49 PM, John Bytheway <jbytheway+boost@gmail.com>wrote:
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
On 28/07/11 19:07, Jeffrey Lee Hellrung, Jr. wrote: <snip> 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; }
Awesome! Unfortunately, not supported in Visual Studio yet :( - Jeff