Vektor templatisierter Objekte
-
Hi,
ich bin Templates-Neuling und habe folgendes Problem:
Ich habe eine Klasse, die Parameter beinhalten soll, das ganze für double, int und noch ein paar andere. Also:
template T; class Parameter { private: T value; public: void Set(T val); T Get(); };In einer anderen Klasse soll ein Vektor solche Parameter beinhalten. Allerdings nicht nur solche, die die gleiche Template-Belegung haben, sondern alle sollen aufgenommen werden können.
std::vector<Parameter> parameters;Mit Vererbung würde ich einfach alle Parameter-Klassen von einer gemeinsamen Vaterklasse ableiten, aber wie mache ich das mit Templates?
Gruß, K.B.
-
Das ganze geht afaik mit boost::any (oder vergleichbaren).
Allerdings wuerde ich erst noch einmal genau darueber nachdenken, ob du das ganze nicht anders loesen kannst - ich vermute eher ein Designproblem.
-
Und @Karl, du musst wissen, dass ein Parameter<int> ein anderer Typ ist als Parameter<double>. Ein vector kann aber (außer vielleicht durch Sachen wie boost::any) nur Objekte des selben/gleichen Typs aufnehmen.
-
Da mich dieses Problem auch interessiert, habe ich mich mal zu
boost.anyerkundigt, und folgende Lösung angefertigt:template<class T> class Parameter { private: T element; public: void set(T val) { element = val; } T get() { return element; } }; int main() { std::vector<boost::any> vec; Parameter<int> obj; obj.set(14); boost::any blub(obj); vec.push_back(blub); std::cout << vec.at(0) /* ??? */ }Die Aufnahme von
objinboost::anyklappt wunderbar, nur wie kommt man dann wieder an den Inhalt vonany, also an das vorher eingefügte Objektobj?
-
Hier ganz unten steht, wie mans machen kann.
-
Wunderbar, vielen Dank.
-
Ich habe folgende Situation. Aus einem vector<any>, der mit Instanzierungen meiner eigenen Template-Klasse unter Verwendung verschiedener Typen gefüllt wird. Irgendwann möchte ich dann eine Methode dieser Objekte aufrufen.
Mit fields[i].type() bekomme ich ja immerhin schonmal den quasi "zusammengesetzten" Typ aus meiner Klasse und dem darin benutzten Typ. So wie ich das sehe, müsste ich jetzt any_cast benutzen, um dann anschließend die erwünschte Methode aufzurufen. Aber im Moment sehe ich nur die Möglichkeit, mittels switch alle Fälle zu unterscheiden und dann jeweils "manuell" ein Casting zum richtigen Typ zu schreiben. Das wird aber doch schnell unpraktisch.
Kann man es nicht so einrichten, dass ich any_cast irgendwie den vorher bestimmten Typ in den spitzen Klammern mitgebe, und dann quasi mit einmal Casten alle Fälle und alle möglichen Typen abdecke?
-
Was ist denn an der Vererbungs-Version schlecht?
class AbstractParameter { public: virtual void blubb() = 0; }; template <class T> class Parameter : public AbstractParameter { // ... }; std::vector<boost::shared_ptr<AbstractParameter> > p; // ... p[0]->blubb();Schlecht?
-
Prinzipiell nichts (obwohl ich die auch gar nicht erwähnt hatte). Aber ich benutze auch plain old data, und da müsste ich dann wieder Wrapper-Klassen schreiben. Das mag zwar eleganter sein, scheint mir aber dafür mit relativ viel Overhead erkauft zu sein. Obwohl es mir andererseits natürlich diese zusätzliche Library ersparen würde. Mal schauen, was am Ende günstiger ist.
-
den overhead baust du dir mit any außerdem sonst selbst ein (switch). irgendwo muss die entscheidung, welche funktion für den konkreten typen aufgerufen wird, ja getroffen werden. du hast die wahl: in deinem switch oder dank eingebauter polymorphie?