$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
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