Boost logo

Boost :

From: Mat Marcus (mmarcus_at_[hidden])
Date: 2000-10-02 05:44:37


At 8:22 AM -0400 9/30/00, John Maddock wrote:
>
>Unfortunately, is_pointer is the only type-traits template I've been able
>to get working more or less correctly with this technique. Attempting to
>use the same technique with is_array, is_member_pointer, is_same, and
>is_reference all fail: either because the language doesn't allow it, or
>more often, internal compiler errors, or downright incorrect function
>overload resolution.
>
>If there are any cunning artificers out there that can extend this to any
>of the templates mentioned (especially is_reference), I would be very happy
>to hear about it!

is_same is fairly straightforward using the "pointer trick" below.
is_ref had eluded us until David's post:

At 8:49 AM -0400 9/30/00, David Abrahams wrote:
>
>If you have some way of determining whether an expression is a compile-time
>constant, I can help. Of course, it treads into "undefined behavior"
>territory, but:
>
>template <class T>
>struct Holder {
> T x;
> Holder();
>};
>
>is_reference<T> :=
>is_compile_time_constant<(std::size_t)&((Holder<T>*)0)->x>
>
>Probably not much help, though :(
>

Au contraire. I believe this is a key observation. Thanks! We hadn't
solved ISREF yet. In our work we've been using an ISCONST
metafunction that uses IsNonConstPointer for a discriminator. That is
(roughly)

char IsNonConstPointer(void*);
int IsNonConstPointer(...);

template <class T>
struct ISCONST {
     enum {RET = (sizeof(IsNonConstPointer((T*)0)) == 1)}; // The pointer trick
};

If we combine this with your idea we could try

template <class T>
struct ISREF {
    enum {RET = sizeof(IsNonConstPointer(&((Holder<T>*)0)->x) == 1)};
};

I can't wait to go to work to try this on my Windows compiler. (Did I
just say that? :-| ). Too bad Metrowerks' sizeof operator doesn't
work.

- Mat


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