Boost logo

Boost :

From: David Abrahams (dave_at_[hidden])
Date: 2002-11-29 14:09:51


Gennaro Prota <gennaro_prota_at_[hidden]> writes:

> On Thu, 21 Nov 2002 19:15:21 -0500, David Abrahams
> <dave_at_[hidden]> wrote:
>
>>Thoughts?
>
>
> This is one... A nice thing about the problem you are talking about is
> that any function having a parameter of type T is in fact a general
> "detector" of convertibility to T (It's also worth noting that it
> detects convertibility of an *expression*, so it is fundamentally
> different from usual templates like is_convertible<T, U> and the
> like). Well, once you have it it's easy to enforce either
> convertibility _and_ non-convertibility. As an example of the latter,
> this is a trivial way to cause a compile-time error if 'expr' is
> implicitly convertible to the type T.
>
>
> // untested code following
> //
>
> typedef char (&no_type)[1];
> typedef char (&yes_type)[2];
>
> template <typename T>
> struct identity { typedef T type;};
>
> template <typename T>
> yes_type implicit_cast (typename identity<T>::type x) {
> return x;
> }
>
> template <typename T, std::size_t sz >
> struct check_helper{
> /*
> * empty
> */
> };
>
> template <typename T>
> struct check_helper<T, sizeof(no_type)> {
> typedef T type;
> };
>
>
> template <typename T>
> no_type implicit_cast (...);
>
> #define EXPLICIT_CAST(dst_type, expr) \
> ( static_cast< check_helper<dst_type, \
> sizeof(implicit_cast<dst_type>(expr)) > \
> :: type>(expr) )
>

Very interesting! Now the macro starts to look useful. However, the
above function shouldn't be called implicit_cast.

OK, here's what I propose:

    * implicit_cast as Peter proposed it

    * BOOST_IMPLICIT_CAST and BOOST_EXPLICIT_CAST as Gennaro proposed
      them.

The latter two can be used in compile-time constant expressions.

> So it looks like we can separate the two 'directions' in which
> static_cast works in two distinct facilities. Maybe this has already
> been discussed here though, I don't know (Actually there's at least
> one limitation: you can't use a local type for T, but... c'est la
> vie!)
>
>
> Also, a static assertion facility (for expressions) can be easily
> implemented:
>
> #define ASSERT_NON_IMPLICITLY_CONVERTIBLE(T, expr) \
> typedef char PASTE (name_, __LINE__) \
> [ \
> sizeof(no_type) == sizeof(implicit_cast<T>(expr)) \
> ];
>

I think we ought to have new traits for implicitly_convertible and
explicitly_convertible. You can always wrap BOOST_STATIC_ASSERT around
that to get the above behavior.

-- 
                       David Abrahams
   dave_at_[hidden] * http://www.boost-consulting.com
Boost support, enhancements, training, and commercial distribution

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