Instanzierung von Objekten vom Typ eines Template-Parameters
-
Hallo zusammen,
ich hab mal ne Frage bezüglich Instanzierung von Objekten vom Typ eines Template-Parameters in Template-Funktionen.
Hier mal ein kurzes Beispiel
#include <iostream> class A{ }; template<typename T> void doSomething(){ T inst; } int main(int argc, char**) { doSomething<A>(); }Jetzt werden vor der Instanziierung noch Variablen angelegt, die je nach Typ interessant für den Konstruktor sind.
Deswegen habe ich an folgendes Konstrukt gedacht:class A{ }; class B{ public: B(int i){ } }; template<typename T> T createObject(int i){ return T(); } template<> B createObject<B>(int i){ return B(i); } template<typename T> void doSomething(){ int i = 0; T inst(createObject<T>(i)); } int main(int argc, char**) { doSomething<A>(); doSomething<B>(); }Sobald ich jedoch den Copy-Konstruktor verbiete, funktioniert das verständlicherweise nicht mehr.
private: B(const B& b){ }Deswegen habe ich an ein Konstrukt mit einer Hilfsklasse gedacht wie im folgenden Beispiel:
#include <iostream> class A{ public: void print(){ std::cout << "A" << std::endl; } }; class B{ public: B(int i){ } void print(){ std::cout << "B" << std::endl; } private: B(const B& b){ } }; template<typename T> class FactoryHelper : public T{ public: FactoryHelper(int i) : T(){ } }; template<> class FactoryHelper<B> : public B{ public: FactoryHelper(int i) : B(i){ } }; template<typename T> void doSomething(){ int i = 0; FactoryHelper<T> inst(i); inst.print(); } int main(int argc, char**) { doSomething<A>(); doSomething<B>(); }Wie würdet ihr sowas lösen?
Also ich würde das Objekt gerne auf dem Stack haben. Ansonsten bieten sich natürlich Möglichkeiten das Objekt ohne Kopieren
zurückzugeben.Gruß,
XSpille
-
Für diesen Anwendungsfall sieht das so eigentlich schön geradlinig aus. Allerdings kann die Notwendigkeit solcher Kunstgriffe auf andere Designmängel hindeuten - was genau hast du eigentlich vor?
-
XSpille schrieb:
Wie würdet ihr sowas lösen?
template<typename T> void doSomething(const T& inst) { // do something with inst } int main() { A a; doSomething(a); B b(1); doSomething(b); return 0; }Wenn A und B unterschiedliche Konstruktoren haben, sind die Ctors einfach nicht geeignet um sie in einem Template aufzurufen. Die Typen sind an dieser Stelle einfach anders.
Deine FactoryHelper Sache ist auch überhaupt nicht erweiterbar. Wenn jetzt C ankommt mit einem Ctor mit Signatur (int, int) musst du alles ändern.