Re: Call a member function only if it exists
Jens Breitbart wrote:
Hi,
I wrote a framework, which uses callback functions. Currently all
classes used with the framework have to implement the callback
function. I would like to define a default behavior for all classes,
that do not implement the function. I am aware that this could easily
be done, by defining a base class and require that all classes used
with the framework inherit for this base class, but I would prefer to
do this without inheritance. The code I have in mind looks similar to
the one below, but I failed to write the caller template.
void f () {
// default behavior
}
struct A {
void f () {
// special behavior for objects of type A
}
};
struct B {
};
int main () {
A a;
B b;
//caller<A>::f(a); // should call a.f()
//caller<B>::f(b); // should call f()
return 0;
}
Any suggestion how to solve the problem would be highly appreciated.
the code is base on
http://groups.google.com/group/comp.lang.c++/browse_thread/thread/c0ab71fc3e1ff59
#include <iostream>
template<class T> struct has_member_f;
template<class R, class C>
class has_member_f<R C::*> {
private:
template<R C::*> struct helper;
template<class T> static char check(helper<&T::f>*);
template<class T> static char (& check(...))[2];
public:
static const bool value = (sizeof(check<C>(0)) == sizeof(char));
};
namespace boost { // no dependency of boost
template <bool B, class T = void>
struct enable_if_c {
typedef T type;
};
template <>
struct enable_if_c<false, void> {};
} // namespace boost
void f() {
std::cout << "::f()" << std::endl;
}
struct caller {
template <class T>
static void f(
T& t,
typename boost::enable_if_c<
has_member_f<void (T::*)()>::value
>::type* = 0) {
t.f();
}
template <class T>
static void f(
T& t,
typename boost::enable_if_c<
!has_member_f<void (T::*)()>::value
>::type* = 0) {
::f();
}
};
// client code below
struct A { };
struct B {
void f() {
std::cout << "B::f" << std::endl;
}
};
int main() {
std::cout
<< has_member_f<void (A::*)()>::value << '\n'
<< has_member_f<void (B::*)()>::value << std::endl;
A a;
caller::f(a);
B b;
caller::f(b);
}
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]