|
Boost : |
From: Paul Mensonides (pmenso57_at_[hidden])
Date: 2002-04-22 21:45:41
I posted this at comp.std.c++, but I don't think it went through--I'm not trying
to 'cross-post'. :)
I'm curious about the legality of the following construct. It is attempting to
test whether a give type 'T' has a member function 'self'.
template<class T> struct has_self {
private:
typedef char small_t;
typedef char (& large_t)[256];
template<class U> struct helper {
template<void (U::*)(void)> struct inner { };
};
template<class U> static small_t check( typename helper<U>::template
inner<&U::self>* );
template<class U> static large_t check( ... );
public:
static const bool value = sizeof(check<T>(0)) == sizeof(small_t);
};
struct X { }; // no 'self'
struct Y {
void self(void) {
return;
}
};
int main() {
std::cout
<< has_self<X>::value << '\n'
<< has_self<Y>::value << &std::endl;
return 0;
}
This compiles and words as desired on Comeau C++, but I'm wondering if it is
*legal* C++. I'm using it to create an unbounded (theoretically) multi-method
dispatcher, but I need to check where a type has that member function. If not,
then I need to revert (at compile-time) to using dynamic_cast.
By the way, I already have it working as long as the object has the following
definition:
struct some_type {
virtual void self(void) {
throw this;
}
};
For a double dispatch:
struct X {
virtual void self(void) {
throw this;
}
};
struct Y : X {
void self(void) {
throw this;
}
};
struct handler {
typedef const char* return_type;
inline return_type operator()(X& a, X& b) {
return "default used";
}
inline return_type operator()(Y& a, Y& b) {
return "Y Y found";
}
};
int main() {
typedef TYPELIST(( X, Y )) types;
MULTI_METHOD(( types, types )) multi;
X x;
Y y;
X& rx = x;
X& ry = y;
std::cout << multi( rx, ry, handler() ) << '\n';
std::cout << multi( ry, ry, handler() ) << &std::endl;
return 0;
}
With __VA_ARGS__ from C99, I could reduce it to:
MULTI_METHOD(TYPELIST(X, Y), TYPELIST(X, Y)) multi;
The main problem is that the necessity of 'self' is intrusive, so I want to
detect if it exists and if not use a dynamic_cast implementation instead.
Paul Mensonides
(P.S. note to Andrei Alexandrescu...)
Andrei, I haven't tested the performance characteristics when compared to Loki's
multi-methods, but it seems to work fairly quickly. With a good exception
handling mechanism it can be even better.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk