|
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