Boost logo

Boost :

From: Aleksey Gurtovoy (alexy_at_[hidden])
Date: 2000-12-22 07:19:35


Dave Abrahams wrote:
> If you can implement this without partial specialization or get my company
> to drop MSVC you'll be my hero ;-).

Mine too :) BTW, there a was a moment when I thought that we can really do
this on MSVC - using the fact that it compiles an ill-formed code like this
one:

template<class T1>
struct is_same_part_1 {
  template<class T2> struct part_2 { enum { value = false }; };
  template<> struct part_2<T1> { enum { value = true }; };
};

template<class T1, class T2>
struct is_same : is_same_part_1<T1>::template part_2<T2> {};

And the resulting template can be even used on incomplete types (and it even
gives the correct results :)! The fact that it is ill-formed didn't bother
me much because VC++ is not a C++ compiler anyway, and given that VC7.0
compiles this code too, I convinced myself that I can be pretty sure that
the "feature" will be here for years :). So 3 minutes later I already had
simple and elegant (if this epithet can be applied to a non-conforming code
;) 'is_const' and 'is_volatile':

template<class T>
struct is_const_impl {
  template<class U> struct inner { enum { value = false }; };
  template<> struct inner<T const> { enum { value = true }; };
};

template<class T>
struct is_const : is_const_impl<T>::template inner<T> {};

template<class T>
struct is_volatile_impl {
  template<class U> struct inner { enum { value = false }; };
  template<> struct inner<T volatile> { enum { value = true }; };
};

template<class T>
struct is_volatile : is_volatile_impl<T>::template inner<T> {};

...and was pretty sure that 'remove_pointer' and 'is_reference' are already
in our pocket.. But here the exciting part ends :(, because the following
code doesn't work:

template<class T>
struct remove_reference_impl {
  template<class U> struct inner { typedef U type; };
  template<> struct inner<T&> { typedef T type; };
};

template<class T>
struct remove_reference : remove_reference_impl<T>::inner<T> {};

BOOST_STATIC_ASSERT((is_same<int, remove_reference<int&>::type>::value)); //
error

I think that I even understand why, but I'll pass the right of explanation
of this one to other intrested parties (if there are any :). Still, the
templates which do work probably should replace the current ones in
'ob_type_traits.hpp' header (#ifdef-guarded in the way that they will be
used only with MSVC, of course).

  --Aleksey


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