|
Boost : |
From: Gennaro Prota (gennaro_prota_at_[hidden])
Date: 2002-11-26 05:34:47
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) )
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)) \
];
and maybe this is what someone may be interested in (rather than the
two macros for static-casting).
Genny.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk