variadic factory
-
Hey ich hab es öfter das ich ne factory brauche um eine überschaubare menge an objekte mit gleicher base class zu aus strings zu erstellen. Wenn die alle das gleiche interface zum erstellen haben geht das auch super, aber ich dachte mir ich probier das mal mit variadic templates (unterschiedlichem interface), komm da aber nicht so richtig weiter :D.
struct Base { }; struct One : public Base { One(int a, std::string b) : a(a), b(b) {} int a; std::string b; }; struct Two : public Base { Two(One a, double b) : a(a), b(b) {} One a; double b; }; // perfekt wäre: Factory<Base> fact; fact.Register<One>("one"); fact.Register<Two>("two"); Base *one = fact.Create("one", 1, "hello"); Base *two = fact.Create("two", One(2, "muh"), 1.337);Es stockt beim abspeichern/aufrufen mit variadic templates, mit ist immer die template signatur im weg um das in nen container zu packen, steh da voll auf dem schlauch. Hab schon einiges durchgelesen aber komm nicht wirklich weiter. Hoffe ihr könnt mir helfen

-
Wo ist da jetzt der Vorteil zu dem hier?
Base *one = new One(1, "hello"); Base *two = new Two(One(2, "muh"), 1.337);
-
Naja, man benutzt eine Factory, um halt dynamisch im Hintergrund entscheiden zu können, was anderes zurück zu geben. Z.B. weil sich eine Situation oder Konfiguration geändert hat, dann muss man den Aufrufer-Code nicht anfassen. (nur an einer Stelle in der Factory)
Z.B. durch nachladen einer DLL, kann sich das ändern.// in anderer DLL class SpezialOne : public One {}; fact.Register<SpezialOne>("one"); // alter Client-Code Base *one = fact.Create("one", 1, "hello"); // gibt SpezialOne zurückAber das war glaube ich nicht sein Problem.

EDIT: ich glaube, ich habe Unsinn geschrieben...

-
foofel schrieb:
Es stockt beim abspeichern/aufrufen mit variadic templates, mit ist immer die template signatur im weg um das in nen container zu packen, steh da voll auf dem schlauch. Hab schon einiges durchgelesen aber komm nicht wirklich weiter. Hoffe ihr könnt mir helfen

So wie Du Dir die Factory vorstellst, brauchst Du Laufzeitpolymorphie.
z.B. "Interfaces" zum Erstellen der Subklassen in Base:struct Base { virtual Base* create(int a, std::string b) { throw "njet"; } virtual Base* create(int a, std::string b, double c) { throw "njet"; } // für Two };Und dann einfach eine map<string, Base*> in der Factory...