Callback-Funktion an Template-Klasse
-
Ich habe hier ein etwas älteres Projekt mit Strukturen, die hauptsächlich als verketteten Listen verwendet werden. Nun möchte ich mir das Leben etwas einfacher machen und hab mir einen Smart-Pointer-Wrapper dazu geschrieben. Das funktioniert auch sehr gut, nur möchte ich das Ganze nun etwas abstrakter machen. Mein Smart-Pointer funktioniert momentan nur für exakt einen Typ dieser Strukturen und das möchte ich mit Templates verallgemeinern.
Geben sind beispielsweise zwei structs:
struct A{ int x1; int x2; A *next; }; struct B{ double x1; double x2; B *next; };Zu diesen beiden Klassen existieren jeweils eigene Funktionen, die eine verkettete Liste aus diesen Typen freigeben. Beispiel:
FreeLinkedA(A **pStart); FreeLinkedB(B **pStart);Mein Konstrukt sieht momentan so aus:
template <class T, void (*freefnct)(T *param), int (*countfnct)(const T param), bool (*appendfnct)(T *source, T *append)> class AxSmartPointer{ protected: T m_value; public: AxSmartPointer() : m_value(NULL) { } AxSmartPointer(T value) : m_value(value){ } ~AxSmartPointer(){ Clear(); } public: T operator ->(){ return m_value; } void operator = (T value){ Clear(); m_value = value; } void operator += (T value){ if(IsNULL()) m_value = value; else appendfnct(&m_value, &value); } int Count() const { if(IsNULL()) return 0; return countfnct(m_value); } bool IsNULL() const { return m_value == NULL; } void Clear(){ if(!IsNULL()) freefnct(&m_value); m_value = NULL; } operator T(){ return m_value; } private: AxSmartPointer(const AxSmartPointer &rhs); };Von diesem template hab ich mir eine Klasse erzeugt:
class StructAPtr : public AxSmartPointer<A*, FreeLinkedA, CountLinkedA, AppendLinkedA>{ };Wenn ich nun den Smart-Pointer verwenden will, zum Beispiel hier:
StructAPtr myA(FunctionWhichReturnsLinkedA());Bekomme ich folgende Fehlermeldung:
error C2664: 'StructAPtr::StructAPtr(const StructAPtr &)' : cannot convert parameter 1 from 'A *' to 'const StructAPtr &'Irgendwas mach ich also falsch. Kann mir jemand helfen?
-
Spricht irgendetwas dagegen, std::list und TR1::shared_ptr zu benutzen? Oder einen Pointer Container aus den boost Bibliotheken?
-
Wenn du mit std::list meinst, dass ich die verketteten Liste dadurch ersetzen soll, dann spricht der Aufwand dagegen. Das Projekt ist sehr groß und hunderte Funktionen erwarten die verkette Liste als Parameter.
Gegen die Verwendung von TR1 spricht, dass ich die Entwicklungsumgebungen von VS 2002 - 2008 unterstützen muss.Ich hab ja im Prinzip nur ein Problem mit dem template. Mein erster Smart-Pointer Ansatz hat ja gut funktioniert, aber eben nur für einen Typ.
-
Source2702 schrieb:
Bekomme ich folgende Fehlermeldung:
error C2664: 'StructAPtr::StructAPtr(const StructAPtr &)' : cannot convert parameter 1 from 'A *' to 'const StructAPtr &'Irgendwas mach ich also falsch. Kann mir jemand helfen?
Es existiert kein Konstructor der ein A* nimmt.
Ich glaube jetzt kannst du das Problem lösen.
-
Der Konstruktor, der ein A* nimmt ist doch im template implementiert:
AxSmartPointer(T value) : m_value(value){ }
-
Source2702 schrieb:
Der Konstruktor, der ein A* nimmt ist doch im template implementiert:
AxSmartPointer(T value) : m_value(value){ }Den erbt dein StructAPtr aber nicht. Also ist er für StructAPtr eben NICHT implementiert. Der Compiler kennt für StructAPtr nur die compilergenerierten Konstruktoren (Default- und Copy-Ctor).
mach stattdessen ein
typedef AxSmartPointer<A*, FreeLinkedA, CountLinkedA, AppendLinkedA> StrustAPtr;dann hast du auch die Ctoren des Templates.