Template-Problem
-
Hallo erstmal!
Irgendwie hab ich grad ein totales Defizit an Durchblick. Und zwar schluckt mein Compiler (gcc 3.2.3) folgenden Code nicht:
ref_counter.h:
//ref_counter.h: defines a class for reference counting #ifndef _TSL_REF_COUNTER_H_ #define _TSL_REF_COUNTER_H_ namespace tsl { class ref_counter { private: unsigned int *_count; void decrement() { if(unique()) delete _count; else --*_count; } public: ref_counter() : _count(new unsigned int(1U)) { } ref_counter(const ref_counter &src) : _count(src._count) { ++*_count; } ref_counter &operator =(const ref_counter &src) { ++*src._count; decrement(); _count = src._count; return *this; } ~ref_counter() { decrement(); } bool unique() const { return *_count == 1; } unsigned int get_count() const { return *_count; } }; } #endif
sp.h:
//sp.h: smart pointer template #ifndef _TSL_SP_H_ #define _TSL_SP_H_ #include <typeinfo> #include "ref_counter.h" namespace tsl { template <typename T> class sp { template <typename F> friend class sp; private: T *_ptr; ref_counter _counter; sp(T *fresh, const ref_counter &counter) : _ptr(fresh), _counter(counter) { } public: sp() : _ptr(0) { } sp(T *fresh) : _ptr(fresh) { } ~sp() { if(_counter.unique() && _ptr) delete _ptr; } bool unique() const { return _counter.unique(); } unsigned int get_references() const { return _counter.get_count(); } bool null() const { return _ptr == 0; } T *get_ptr() const { return _ptr; } template <typename T2> sp<T2> cast() const { if(_ptr) { T2 *ptr = dynamic_cast<T2 *>(_ptr); if(!ptr) throw std::bad_cast(); else return sp<T2>(ptr, _counter); //same object, so copy _counter } else { return sp<T2>(0); } } T &operator *() const { return *_ptr; } T *operator ->() const { return _ptr; } sp<T> &operator =(const sp<T> &src) { if(_ptr != src._ptr) { if(unique() && _ptr) delete _ptr; _ptr = src._ptr; _counter = src._counter; } return *this; } }; template <typename T> inline bool operator ==(const sp<T> &l, const sp<T> &r) { return l.get_ptr() == r.get_ptr(); } template <typename T> inline bool operator !=(const sp<T> &l, const sp<T> &r) { return l.get_ptr() != r.get_ptr(); } template <typename T> inline bool operator <=(const sp<T> &l, const sp<T> &r) { return l.get_ptr() <= r.get_ptr(); } template <typename T> inline bool operator < (const sp<T> &l, const sp<T> &r) { return l.get_ptr() < r.get_ptr(); } template <typename T> inline bool operator >=(const sp<T> &l, const sp<T> &r) { return l.get_ptr() >= r.get_ptr(); } template <typename T> inline bool operator > (const sp<T> &l, const sp<T> &r) { return l.get_ptr() > r.get_ptr(); } } #endif
sp_template.h:
#include "sp.h" #include <iostream> using namespace std; using namespace tsl; class foo { public: template <typename T> sp<T> create_object() { return sp<T>(new T()); } }; template <typename T2> sp<T2> bar() { foo obj; return obj.create_object<T2>(); } int main() { foo obj; sp<int> int_ptr= obj.create_object<int>(); cout << *int_ptr << endl; cout << *(bar<float>()) << endl; return 0; }
Der Compiler sagt dazu folgendes:
src/sp_template.cpp: In function `tsl::sp<T2> bar()': src/sp_template.cpp:21: syntax error before `>' token src/sp_template.cpp:22: warning: no return statement in function returning non-void
Es ist zum Verrücktwerden!
Ich hab keinen Plan, was ich falsch mache, deshalb wäre ein kleiner Hinweis mit Erklärung ganz nett...
-
bitte nächstes mal mit hinweis auf die fehlerzeile
template <typename T2> sp<T2> bar() { foo obj; return obj.template create_object<T2>(); //hier }
sonst wird das nicht als template interpretiert (< und > haben noch andere funktionen). syntactic sugar
-
davie schrieb:
bitte nächstes mal mit hinweis auf die fehlerzeile
template <typename T2> sp<T2> bar() { foo obj; return obj.template create_object<T2>(); //hier }
sonst wird das nicht als template interpretiert (< und > haben noch andere funktionen). syntactic sugar
Sollte das tatsächlich der Fehler gewesen sein, dann ist das ein Fehler im Compiler. foo ist *kein* Template und obj.create_object damit *kein* abhängiger Name. Insofern muss der Compiler den Aufruf von create_object auch *ohne* das template als Templatemethode erkennen und auflösen können.
Das "template" wäre nur nötig, wenn foo selbst ein Template und gleichzeitig von T2 abhängig wäre.
Naja, Template-Lookupregeln sind nicht das einfachste der Welt, insofern ist es wohl nicht verwunderlich, dass einige Compiler da noch immer Schwierigkeiten mit haben.
-
uff muss mir das morgen anschauen. bin im moment zu müde.
und da ich auf der suche nach dem fehler die wurscht kompiliert hab und ebenfalls gcc verwende, und das so geklappt hat, ...
gute nacht
-
Danke!!! Hat funktioniert.
Woher weiß man sowas?
EDIT: Shit, bekomm nicht mal so einen kurzen Beitrag ohne Fehler hin! Was ist nur los?