Boost logo

Boost :

From: David Abrahams (david.abrahams_at_[hidden])
Date: 2002-03-13 10:33:21


It seems that the known technologies for writing type traits for
compilers without partial specialization nearly always force us to
choose between supporting array types and supporting abstract classes.
Let's just look at is_pointer, for an example:

----------
   struct pointer_helper
   {
      pointer_helper(const volatile void*);
   };
   yes_type BOOST_TT_DECL is_pointer_helper(pointer_helper);
   no_type BOOST_TT_DECL is_pointer_helper(...);

template <typename T>
struct is_pointer
{
private:
   static T t;
public:
   BOOST_STATIC_CONSTANT(bool, value =
                (::boost::type_traits::ice_and<
                  ::boost::type_traits::ice_not<
                     ::boost::is_reference<T>::value
>::value,
                  ::boost::type_traits::ice_not<
                     ::boost::is_array<T>::value
>::value,
                  (::boost::type_traits::ice_or<
                       (1 == sizeof(detail::is_pointer_helper(t))),
                       (1 == sizeof(detail::is_function_tester(t)))
>::value)
>::value ) );
};
template <>
struct is_pointer <void>
{
   BOOST_STATIC_CONSTANT(bool, value = false);
};
-----------

The above is our current implementation, which cannot be instantiated
when T is a class with an unimplemented pure virtual function.

Now let's examine an alternative implementation, which doesn't support
array types, but supports abstract classes:

---------
template <class T>
yes_type BOOST_TT_DECL is_pointer_helper(T*(*)());
no_type BOOST_TT_DECL is_pointer_helper(...);
template <typename T>
struct is_pointer
{
 public:
   BOOST_STATIC_CONSTANT(bool, value =
                  (::boost::type_traits::ice_or<
                       (1 ==
sizeof(detail::is_pointer_helper((T(*)())0))),
                       (1 == sizeof(detail::is_function_tester(t)))
>::value)
>::value ) );
};
----------

Leaving aside from the technical argument that the 2nd version is much
simpler, I wonder if we have made the right choice in our support for
array types over abstract classes. In the work I'm doing, with function
arguments and return values, it seems to me that abstract classes are
going to arise far more often than arrays.

In particular, it would be very useful to me if I could instantiate
is_class<T> for abstract classes. It's much less important to me that it
work for array types.

Thoughts?
Dave

+---------------------------------------------------------------+
                  David Abrahams
      C++ Booster (http://www.boost.org) O__ ==
      Pythonista (http://www.python.org) c/ /'_ ==
  resume: http://users.rcn.com/abrahams/resume.html (*) \(*) ==
          email: david.abrahams_at_[hidden]
+---------------------------------------------------------------+


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