2013-02-27 16 views
5

Ich schreibe eine Bibliothek, die eine gute Menge von beiden Vorlagen Tricks und boost :: any enthält. Ich habe in einer Situation führen, wo ich dies im Wesentlichen haben:boost :: any und templates

boost::any a1, a2, a3, a4; 

... und ich brauche eine Funktion aufzurufen, die wie folgt aussieht:

template <typename A1, typename A2, typename A3, typename A4> 
void somefunc (A1 a1, A2 a2, A3 a3, A4 a4); 

ich auf eine obszöne verschachtelte Serie zurückgreifen konnte von if-Anweisungen, aber unter der Annahme, dass ich 10 unterschiedliche Typen handle, sind das 10.000 if-Anweisungen! Boost Präprozessor könnte hier helfen, aber das ist immer noch eine schreckliche Lösung.

Gibt es eine bessere Möglichkeit, eine Template-Funktion mit dem Inhalt eines boost :: any aufzurufen, ohne auf diese Art von Wahnsinn zurückzugreifen? Soweit ich das beurteilen kann, gibt es das nicht.

+0

Nur die Benutzer der 'boost :: any' Die Instanz kann den exakten Wert zur Laufzeit erhalten (indem sie einen hardcoded Typ liefert), Sie können diese Funktion nicht mit dem Wert aufrufen, der in 'boost :: any' enthalten ist, weil ihr Typ * zur Kompilierungszeit * gelöscht wurde. Was ist das größere Problem, das Sie versuchen zu lösen? 'boost :: any' ist ziemlich low-level. – GManNickG

+3

Haben Sie alle 'any'-Objekte als ein Objekt, und wenn Sie alle auf einmal setzen, sichern Sie auch einen Zeiger auf die richtige' somefunc' Instanziierung (z. B. '& somefunc '). – Xeo

+0

@GManNickG Das größere Problem, das ich versuche zu lösen, beinhaltet die automatische Generierung von Lua-Bindungen auf der einen Seite und eine boost :: any, die das Ergebnis einer beliebigen asynchronen Funktion enthält. In dieser Situation kann keiner durch den anderen ersetzt werden. – Xtapolapocetl

Antwort

10

Wenn alle Ihre any Objekte gleichzeitig gesetzt werden können, können Sie den Typ für den Funktionszeiger dann hart und genau dort codieren. Fülle alles in ein separates Objekt und du kannst loslegen. Dies ist im Grunde ein Doppeltnehmen auf type-erasure und auch durch virtuelle Funktionen implementiert werden könnte (wie, wie boost::any arbeitet intern), aber Ich mag diese Version mehr:

// note that this can easily be adapted to boost::tuple and variadic templates 
struct any_container{ 
    template<class T1, class T3, class T3> 
    any_container(T1 const& a1, T2 const& a2, T3 const& a3) 
    : _ichi(a1), _ni(a2), _san(a3), _somefunc(&somefunc<T1, T2, T3>) {} 

    void call(){ _somefunc(_ichi, _ni, _san); } 

private: 
    boost::any _ichi, _ni, _san; 
    // adjust to your need 
    typedef void (*func_type)(boost::any&, boost::any&, boost::any&); 
    func_type _somefunc; 

    template<class T1, class T2, class T3> 
    void somefunc(boost::any& a1, boost::any& a2, boost::any& a3){ 
    // access any objects with 'boost::any_cast<TN>(aN)' 
    } 
}; 
+0

Brilliant, danke. – Xtapolapocetl

+0

+1, insbesondere für die Variablen _ichi, _ni und _san. –