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.
#include <iostream>
#include <cstdlib>
void f(){ std::cout<<"Global!"<<std::endl; }
struct A
{
void f()const{ std::cout<<"Local!"<<std::endl; }
};
struct B
{
};
// Helpers for detecting the signature of f
template<typename T, void (T::*)()const >
class signature_f_1
{
public:
typedef T type;
};
template<typename T1, typename T2>
class signature_f_2
{
public:
static const bool value = false;
};
template<typename T>
class signature_f_2<T, typename signature_f_1<T, &T::f>::type >
{
public:
static const bool value = true;
};
template<typename T>
class signature_f
{
public:
static const bool value = signature_f_2<T,T>::value;
};
// Helpers for performing the function call
template<typename T, bool HAS_FUNCTION_F> class caller_;
template<typename T> class caller_<T,true>
{
public:
static void f(const T& obj) { obj.f(); }
};
template<typename T> class caller_<T,false>
{
public:
static void f(const T& obj){ ::f(); }
};
// Caller implementation
template<typename T> class caller
{
public:
static void f(const T& obj){
caller_<T, signature_f<T>::value >::f(obj);
}
};
int main(int argc, char* argv[])
{
A a;
B b;
caller<A>::f(a);
caller<B>::f(b);
return 0;
}
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]