|
Boost : |
From: Gennaro Prota (gennaro_prota_at_[hidden])
Date: 2003-02-19 06:24:31
On Tue, 18 Feb 2003 19:14:50 +0200, "Rani Sharoni"
<rani_sharoni_at_[hidden]> wrote:
>This is very nice technique. Just notice that you also need to handle void,
>functions and arrays types.
>
>Abstract classes, functions and array types will fail the completion on the
>burn conversion operator since they are not allowed as returns types.
Yeah. The code was just to give the idea, which I could have expressed
in English if it wasn't that my English is even worse than my C++ :-)
>IMHO the main achievement of your technique is that, unlike techniques that
>use conversion constructor to burn user defined conversion, its works for
>incomplete classes (EDG and GCC complain when trying to pass lvalue of
>incomplete class to function that take ellipsis as an argument).
Yes. Attempting lvalue-to-rvalue conversion of an expression of
incomplete type makes the program ill-formed.
>Here is a possible is_enum implementation using your technique:
>
>
>template<typename T> struct convertible { operator T&() const; };
>
>template<typename T>
>struct is_enum2
>{
> static yes test(int);
> static no test(...);
>
> struct not_enum {};
>
> typedef typename select_type< is_fundamental<T>::value ||
>is_reference<T>::value, not_enum, convertible<T> >::type T2;
>
> static T2& make();
>};
>
>
>
>template<typename T>
>struct is_enum
>{
> enum { value = sizeof(is_enum2<T>::test(is_enum2<T>::make())) ==
>sizeof(yes) } ;
>};
Nice :-) BTW, you can avoid the select_type machinery:
template <typename T>
struct Burn {
operator T&() const;
};
// fire-prevention
template <typename T>
Burn<T> ref(T*);
template <typename T>
char* ref(...);
// outside the is_enum<> template
// to help gcc
//
yes is_enum_checker (unsigned long);
no is_enum_checker (...);
template <typename T>
struct is_enum {
static const bool value =
!is_integral<T>::value
&& !is_floating<T>::value
&& sizeof(yes) == sizeof( is_enum_checker (ref<T>(0)) );
};
But this simple stuff is already enough to knock out a lot of
compilers :-/
BTW, I've seen how complex boost::is_reference is. Why so? What
compiler(s) cause(s) most problems?
Genny.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk