|
Boost : |
From: Aleksey Gurtovoy (agurtovoy_at_[hidden])
Date: 2002-10-28 02:40:14
John Maddock wrote:
> Sorry to take so long to look into this, I've been experimenting with
> several compilers (including one that I think we both have,
> but can't talk about), but haven't been able to get this implementation
> working (not even if they accept the is_class implementation).
Intel C++ 6.0 eats it happily, but...
> All complain that you're trying to derive from something that isn't a
> class type, and I think they're right as well. It seems to me that
> is_union_inherit<T> must be instantiated no matter which template
> overload is selected, since it's part of the expression that
> determines which overload to use, rather than part of the function
> signature.
... after re-reading 14.7.1 more carefully I think that you are right. It's
not hard to re-write the trait to avoid this particular trap:
#include "boost/static_assert.hpp"
#include "boost/config.hpp"
typedef char (&no_tag)[1];
typedef char (&yes_tag)[2];
template < typename T > struct is_union_inherit
: T { typedef T type; };
template< typename U > yes_tag is_union_class_helper(
typename is_union_inherit<U>::type*
);
template< typename U > no_tag is_union_class_helper(...);
template< typename T >
struct is_union
{
BOOST_STATIC_CONSTANT(bool, value =
sizeof(is_union_class_helper< T >(0))
== sizeof(no_tag)
);
};
union U {};
class C {};
struct S {};
BOOST_STATIC_ASSERT(is_union<U>::value);
BOOST_STATIC_ASSERT(!is_union<int>::value);
BOOST_STATIC_ASSERT(!is_union<C>::value);
BOOST_STATIC_ASSERT(!is_union<S>::value);
But now it doesn't work even on Intel (which, I thought, implements less
restrictive interpretation of 14.8.2 than others). Oh, well. At least the
non-conforming implementation is usable ;).
Aleksey
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk