2009-06-13 10 views
0

Ich möchte in der Lage sein, eine Klasse für eine Member-Funktion zu templatisieren, ohne die Argumente der Member-Funktion wiederholen zu müssen - dh, sie automatisch abzuleiten. Ich weiß, wie dies zu tun ist, wenn ich die Klasse basierend auf wie viele Argumente die Funktion nennt, aber ich möchte auch das ableiten.Wo kann ich einen eleganten C++ - Memberfunktionsvorlagen-Wrappermechanismus finden, oder wie kann ich ihn erstellen, ohne zu boosten?

So etwas wie dies, obwohl dies nicht (zumindest in MSVC 2008 sp1, die mein Ziel Compiler) funktioniert:

class Foo { 
    void func0(); 
    int func2(char *, float); 
}; 

template<typename T> class Wrapper; 

// specialize for zero-argument void func 
template<typename Host, void (Host::*Func)()> class Wrapper<Func> : public Base { 
    ... specialization goes here ... 
}; 

// specialize for two-argument value func 
template<typename Host, typename Ret, typename Arg0, typename Arg1, Ret (Host::*Func)(Arg0, Arg1)> class Wrapper<Func> : public Base { 
    ... specialization goes here ... 
}; 

Durch "Base" ich diese polymorph dann behandeln kann. Am Ende mag ich dies verwenden, um eine einfache Wrapper-Syntax für eine Skriptsprache zu erstellen:

WrapClass<Bar> wrap(
    MemberFunction<&Bar::func0>("func0") + 
    MemberFunction<&Bar::func2>("func2") 
); 

jedoch, das nicht funktioniert: die Spezialisierung Syntax ist falsch, weil Sie nicht einen Funktionszeiger bieten können zu einem Typname Argument.

Antwort

1

Ich glaube, dass Sie einen Merkmalansatz nehmen müssen, dessen häufigste Bibliothek Boosts ist, aber wenn Sie Boost vermeiden wollten, wäre es nicht extrem schwierig, Ihr eigenes zu rollen, wenn Sie den Umfang beschränken die Implementierung zu nur Zeiger-zu-Stab-Funktionen und die Merkmale auf denen Sie brauchen (modern c++ design ist ein großes Buch, das die Theorie erklärt). So würde ich es mit den Funktionen function_traits und enable_if von boost machen.

Sie könnten ein generisches Template-Argument verwendet, enable_if es für Funktionszeiger, dann Funktionstypen verwenden (oder geben Sie Merkmale) aus den Informationen ziehen Sie brauchen:

#include <boost/function_types/function_arity.hpp> 
#include <boost/function_types/is_member_pointer.hpp> 

template<typename T, class Enable = void> class Wrapper; 

/* other specializations... */ 

// For member functions: 
template <class T> 
class Wrapper<T, typename enable_if<is_member_pointer<T> >::type> 
{ /* function_arity<T>::value has the number of arguments */ }; 

Siehe this und this

+0

Habe ich nicht die Anforderung "kein Boost" erwähnt? Ich denke, ich habe es nicht getan. Ich habe eine solche Anforderung, tut mir leid, ich habe es nicht erwähnt. Ich werde jedoch in die Boost-Header eintauchen und schauen, was sie getan haben, und die kleine Teilmenge nachahmen, die ich brauche. Ich glaube, ich werde am Ende eine innere Vorlage von Wrapper definieren müssen, die wiederum auf Arity spezialisiert ist. –

+0

haben Sie im Titel getan. Mein Punkt ist jedoch; Um dies zu tun, brauchst du eine Charakterbibliothek, und die einzige, die ich kenne, ist Boost. Wenn du es ohne Boost machen willst, musst du dein eigenes rollen oder ein anderes finden. –

1

Die C++ - Standardbibliothek bietet mem_fun_ref welche Art von funktioniert, wie Sie möchten, obwohl es nur für reine und unäre Funktionen funktioniert. Natürlich können Sie eine Struktur mit allen Parametern als ein Argument verwenden.

+0

Leider kann ich eine Struktur nicht verwenden, weil das nicht mit dem Anwendungsfall der Bindung einer Skriptsprache an eine Menge bestehender Klassen auf eine einfache Art und Weise funktioniert. Danke für den Vorschlag! –

Verwandte Themen