|
Boost : |
From: Daniel Walker (daniel.j.walker_at_[hidden])
Date: 2007-03-31 12:46:42
On 3/30/07, Guillaume Melquiond <guillaume.melquiond_at_[hidden]> wrote:
>
> I am not sure if it will help you though, as I don't know if you can afford to
> protect the class you want to test (bar) into a dummy template (foo),
> so that a
> substitution happens. No template typedef...
OK, I think I got it. The trick was getting the "dummy" template. The
following works on gcc 3.4, 4.0, and 4.1 (not 3.3 and older).
typedef char (&yes)[1];
typedef char (&no) [2];
template< class T > struct type_substitute {};
template< template < class T, class U > class>
struct biary_template_substitute {};
template< class T, class U, class V >
struct has_xxx {
template< class W >
static no f(type_substitute< W >*, ...);
template< class W >
static yes f(type_substitute< W >*
, biary_template_substitute<
W::template xxx
>*);
static const bool value
= sizeof(f<T>(0, 0)) == sizeof(yes);
};
struct foo {
template<class U, class V> struct xxx;
};
struct bar {
template<class U, class V> struct yyy;
};
struct baz {
template<class U> struct xxx;
};
int main()
{
int assert_has_xxx[has_xxx<foo, int, int>::value];
int assert_not_xxx[!has_xxx<bar, int, int>::value];
int assert_not_unary[!has_xxx<baz, int, int>::value];
}
I'm certain this is standard compliant because I took the idea
directly from the 3rd example in section 14.8.2 "Attempting to use a
type in a nested-name-specifier of a qualified-id when that type does
not contain the specified member ...". This also works on Comeau 4.3.9
Alpha online except for the assert_not_unary case. Apparently this is
a common problem among compilers. It doesn't work on msvc 7.1 or 8.0
at all. So, though the other two cases work on msvc (not with the
implementation above but there's another on this thread that works),
to handle this case in msvc we still need a work around.
Thanks for the help!
Daniel
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk