|
Boost : |
From: Paul Mensonides (pmenso57_at_[hidden])
Date: 2002-11-10 04:19:33
----- Original Message -----
From: "Aleksey Gurtovoy" <agurtovoy_at_[hidden]>
> With the cleaned up "type deduction success/error?/failure garbage" :)
Here's a detector for operator(). It isn't perfect because you have to
specify the type of the function, but it's better than nothing:
#include <iostream>
template<class T> class has_function_call {
private:
template<class> struct extract;
template<class R, class O> struct extract<R O::*> {
typedef O type;
};
typedef char small_t;
typedef char (& large_t)[256];
template<T> struct helper;
template<class U> static small_t check(helper<&U::operator()>*);
template<class U> static large_t check(...);
public:
static const bool value =
sizeof(check<typename extract<T>::type>(0)) == sizeof(small_t);
};
struct X {
void operator()(void) {
return;
}
};
struct Y { };
struct Z {
template<class T> T operator()(T v) const {
return v;
}
};
int main(void) {
std::cout
<< has_function_call<void (X::*)(void)>::value << '\n'
<< has_function_call<void (Y::*)(void)>::value << '\n'
<< has_function_call<int (Z::*)(int) const>::value << '\n';
return 0;
}
The interesting part is that it can also be used to detect arbitrary member
functions:
#include <iostream>
#define IMPLEMENT_OP(name, id) \
template<class T> class name { \
private: \
template<class> struct extract; \
template<class R, class O> struct extract<R O::*> { \
typedef O type; \
}; \
typedef char small_t; \
typedef char (& large_t)[256]; \
template<T> struct helper; \
template<class U> static small_t check(helper<&U::id>*); \
template<class U> static large_t check(...); \
public: \
static const bool value = \
sizeof(check<typename extract<T>::type>(0)) ==
sizeof(small_t); \
}; \
/**/
#define IMPLEMENT(id) IMPLEMENT_OP(has_ ## id, id)
IMPLEMENT(clone)
IMPLEMENT_OP(has_function_call, operator())
struct A {
virtual A* clone(void) const {
return new A(*this);
}
int operator()(void) {
return 0;
}
};
int main(void) {
std::cout << has_clone<A* (A::*)(void) const>::value << &std::endl;
std::cout << has_function_call<int (A::*)(void)>::value << &std::endl;
return 0;
}
Of course, this will work on *very* few compilers. :(
Paul Mensonides
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk