Frage zum standard
-
bIce schrieb:
namespace Container { namespace _hidden_ { template <typename C, typename VT/* = C::value_type*/> struct ByValueType { public: static void clear(C & c){ while (c.size() > 0) //wie wärs mit c.clear() ? oder zumindes !empty() statt size()>0 c.erase( c.begin() ); } }; // Spezialisierung für Zeiger template <typename C, typename VT/* = C::value_type*/> struct ByValueType<C, VT*> { public: static void clear(C & c){ //C::iterator ist ein dependent name, also ein typename davor for (C::iterator i = c.begin(); i != c.end(); ++i) delete *i; //btw, du hast vergessen den container zu leeren... } }; } // namespace _hidden_ // diese Funktion zum Freigeben aufrufen. template <class C> void clear(C & c){ //C::value_type ist ein dependent name, also typename davor. _hidden_::ByValueType<C, C::value_type>::clear( c ); } //würde ich nicht machen, lass doch einfach _hidden_ stehen... //denn mit einem #undef _hidden_ kann ich in dein _hidden_ sowieso 'eindringen' #ifndef _hidden_ #define _hidden_ NULL #endif } // namespace Container
btw @Jester:
dieses wissen habe ich arroganterweise von meinen 'Idolen' abgeschaut
-
Mit BCB lässt es sich wunderbar kompilieren, aber unter MinGW kommen nur Fehler.
Das leigt daran, das Fehler drin sind. Du hast zwei typenames vergessen.
namespace Container { namespace _hidden_ { template <typename C, typename VT/* = C::value_type*/> struct ByValueType { public: static void clear(C & c){ while (c.size() > 0) c.erase( c.begin() ); } }; // Spezialisierung für Zeiger template <typename C, typename VT/* = C::value_type*/> struct ByValueType<C, VT*> { public: static void clear(C & c){ for (typename C::iterator i = c.begin(); i != c.end(); ++i) delete *i; } }; } // namespace _hidden_ // diese Funktion zum Freigeben aufrufen. template <class C> void clear(C & c){ _hidden_::ByValueType<C, typename C::value_type>::clear( c ); } #ifndef _hidden_ #define _hidden_ NULL #endif } // namespace Container
-
Warum musste ich auch ausgerechnet jetzt angerufen werden
-
Die Fehler kommen trotzdem
static void clear(C & c){ for (C::iterator i = c.begin(); i != c.end(); ++i) // parse error before `;' token delete *i; } [...] template <class C> void clear(C & c){ ByValueType<C, C::value_type>::clear( c ); // to refer to a type member of a template parameter, use `typename } [...] Und noch paar weitere
EDIT: War bezogen auf den Vorschlag von Jester
Helium, danke es funktioniert.
-
Guck dir Shades Kommentare oder meine Version nochmal an. Dort werden deine Fehler genau beschreiben.
(edit: Kommentar mit C
)
-
also die beiden Fehler sind die typenames.
Und welche anderen Fehler bekommst du noch? ausser zB das i eine undeklarierte variable ist?
@Helium: wir sollten uns einigen wer von uns beiden antwortet :p denn sonst steht immer alles doppelt da...
-
Helium schrieb:
Guck dir Shades Kommentare oder meine Version nochmal an. Dort werden deine Fehler genau beschreiben.
(edit: Kommentar mit C
)
Bevor ich den Beitrag schrieb habe ich den Thread im Browser nicht aktualiesiert. Der Posting war auf den Vorschlag von Jester bezogen. Jetzt funktioniert es. Danke.
Andere Fehler waren Folgefehler.
Z.B. `i' undeclared (first use this function)
-
@Shade of Mine: Mir sind Deine Vorschläge erst auf den zweiten Blick aufgefallen
Danke auf jeden Fall.
wie wärs mit c.clear() ? oder zumindest !empty() statt size()>0
habe nicht gewusst, dass es sowas gibt.
btw, du hast vergessen den container zu leeren...
wenn ich c.erase(i) einfüge kommen laufzeitfehler.
Und außerdem habe ich irgendwo mal gelesen, wo es nicht geleert wurde. (Glaub in Thinking in C++)würde ich nicht mache, lass doch einfach _hidden_ stehen...
denn mit einem #undef _hidden_ kann ich in dein _hidden sowieso 'eindringen'
#ifndef _hidden_
#define _hidden_ NULL
#endifDa steht #define und nicht #undef. Und ich kann nicht auf Klassen zugreifen.
Bsp:
Container::_hidden_::ByValueType<list<int>, list<int>::value_type> bvt;
es kommt dann zu: parse error before `__null'
EDIT: BTW: Borland ist hier also gegen den Standard
-
du solltest nach der schleife einfach c.clear() aufrufen.
wenn du
#define _hidden_ NULLschreibst, dann schreib ich einfach
#undef _hidden_
und kann per
Container::_hidden_
sehr wohl auf alles zugreifen. unnamed namespaces sind hier wohl besser, oder du lässt den namen hidden einfach so stehen - stört ja niemanden...
-
Meckermecker:
Wo ist der Nutzen eines unnamed namespaces? Dann kann der böse User immer noch mit Container:: drauf zugreifen. Ist ein unnamed namespace in einem Header nicht auch eine eher schlechte Idee? Ich kann mir hier zwar nicht konkret vorstellen, wie es zu Fehlern kommen könnte, aber ich würde das struct einfach MySomethingImpl nennen und mich entspannt zurücklehnen. Was kann man damit schon kaputt machen?
Andererseits ist mir das Design der Funktion sowieso suspekt. Ich bin aber wohl auch überdurchschnittlich allergisch gegen besitzende STLContainer<T*>