?
Hilf dir das ein wenig?
#include <iostream>
using namespace std;
struct tag {};
struct default_tag {};
class some
{
public:
int func1() { wcout << L"Called non-tagged method #1.\n"; return 1; }
int func1( tag ) { wcout << L"Called tagged method #1.\n"; return 1; }
int func2( float ) { wcout << L"Called non-tagged method #2.\n"; return 1; }
int func2( float, tag ) { wcout << L"Called tagged method #2.\n"; return 1; }
};
template<bool Tagged>
struct Caller;
template<>
struct Caller<true>
{
template<typename Class, typename FunPtrTyp>
static int call(Class& obj, FunPtrTyp funPtr)
{
return (obj.*funPtr)(tag());
}
};
template<>
struct Caller<false>
{
template<typename Class, typename FunPtrTyp>
static int call(Class& obj, FunPtrTyp funPtr)
{
return (obj.*funPtr)();
}
};
template<typename Class, typename Tag, typename ReturnType>
struct caller_0
{
typedef ReturnType (Class::*DefaultFunPtr)();
typedef ReturnType (Class::*TaggedFunPtr)(tag);
static const bool is_tagged = is_same<Tag, tag>::value;
typedef typename conditional<is_tagged, TaggedFunPtr, DefaultFunPtr>::type FunPtrTyp;
static ReturnType call(Class& obj, FunPtrTyp funPtr)
{
return Caller<is_tagged>::call(obj, funPtr);
}
};
template<typename Tag, typename Class, typename ReturnType>
ReturnType callMe(Class a, ReturnType (Class::*fun)())
{
// Edit: Ups, geht ja noch einfacher:
return caller_0<Class, Tag, ReturnType>::call(a, &Class::func1);
//return caller_0<Class, Tag, decltype((((Class*)nullptr)->*fun)())>::call(a, &Class::func1);
}
int main()
{
some a;
callMe<tag>(a, &some::func1);
callMe<default_tag>(a, &some::func1);
}
Ich glaub ohne variadic templates oder Ellipsen, kommst du nicht bequem so einfach dran vorbei mehrere Argumente zu übergeben.
Edit: Ich sehe gerade nen Fehler in Zeile 64. &Class::func1 ... Naja, jetzt ist es schon zu spät.