template als template übergeben?
-
theta schrieb:
SeppJ schrieb:
Bevor du irgendwann mal unnötige Probleme bekommst, eine Warnung:
Bezeichner die mit _ anfangen oder zwei _ nacheinander enthalten, sind für die Compilerimplementierung reserviert. Wenn man selber solche Namen benutzt, kann es passieren, dass es zu Namenskonflikten kommt.
Gilt aber nicht für Member variablen...
Doch.
-
Shade Of Mine schrieb:
theta schrieb:
SeppJ schrieb:
Bevor du irgendwann mal unnötige Probleme bekommst, eine Warnung:
Bezeichner die mit _ anfangen oder zwei _ nacheinander enthalten, sind für die Compilerimplementierung reserviert. Wenn man selber solche Namen benutzt, kann es passieren, dass es zu Namenskonflikten kommt.
Gilt aber nicht für Member variablen...
Doch.
Ich habe mal nachgeschlagen: Der Sachverhalt ist komplizierter:
Überall (auch für Member) sind reserviert:
- Namen die einen doppelten Unterstrich enthalten
UND - Namen die mit einem Unterstrich gefolgt von einem Großbuchstaben beginnen
Nur im globalen Namensbereich reserviert sind:
- Namen die mit einem Unterstrich beginnen
- Namen die einen doppelten Unterstrich enthalten
-
In 17.4.3.1 ff steht aber nichts davon.
Da sind nur Macro names, Global names und Names with external linkage erwähnt.Simon
-
theta schrieb:
In 17.4.3.1 ff steht aber nichts davon.
Da sind nur Macro names, Global names und Names with external linkage erwähnt.Da steht aber für die von SeppJ bei "überall" erwähnten Konditionen "for any use".
Daraus folgt doch, dass es keine gute Idee ist, einen solchen Namen für irgendwas eigenes zu verwenden. Denn spätestens, wenn die Bibliotheksimplementierung ein Makro dieses Namens definiert, ist völlig Wurst, ob es sich bei Deiner Verwendung um eine Membervariable handelt.
-
Da steht aber für die von SeppJ bei "überall" erwähnten Konditionen "for any use".
Da hätte ich gerne die Ref. in den Standard.
Simon
-
SeppJ schrieb:
Nur im globalen Namensbereich reserviert sind:
- Namen die mit einem Unterstrich beginnen
(und im namespace std)

theta schrieb:
In 17.4.3.1 ff steht aber nichts davon.
Da sind nur Macro names, Global names und Names with external linkage erwähnt.Die Überschrift "Global names" in 17.4.3.1.2 ist da etwas missverständlich. Das bezieht sich nicht auf Bezeichner im globalen namespace sondern allgemein auf namen, die *irgendwo* benutzt werden. Andernfalls würde im zweiten Unterpunkt (Namen die mit Unterstrichen beginnen, [auch ohne folgenden Großbuchstaben]) der Zusatz "for use as a name in the global namespace" keinen Sinn machen.
Siehe auch ausführliche Diskussion hier: http://www.velocityreviews.com/forums/t486491-reserved-identifiers.html
-
theta schrieb:
Da hätte ich gerne die Ref. in den Standard.
17.4.3.1.2 erster Spiegelstrich
-
Danke.
Simon
-
pumuckl schrieb:
SeppJ schrieb:
Nur im globalen Namensbereich reserviert sind:
- Namen die mit einem Unterstrich beginnen
(und im namespace std)

Interessanterweise steht das im Standard nicht so, dort wird ausdrücklich der globale Namensbereich genannt. Das bedeutet wohl, dass in std nur die Namen mit doppeltem Unterstrich und die Namen mit Unterstrich und Großbuchstaben reserviert sind.
-
SeppJ schrieb:
pumuckl schrieb:
SeppJ schrieb:
Nur im globalen Namensbereich reserviert sind:
- Namen die mit einem Unterstrich beginnen
(und im namespace std)

Interessanterweise steht das im Standard nicht so, dort wird ausdrücklich der globale Namensbereich genannt. Das bedeutet wohl, dass in std nur die Namen mit doppeltem Unterstrich und die Namen mit Unterstrich und Großbuchstaben reserviert sind.
17.4.3.1 Abs. 1 S. 1
-
camper schrieb:
SeppJ schrieb:
pumuckl schrieb:
[...](und im namespace std)

Interessanterweise steht das im Standard nicht so, dort wird ausdrücklich der globale Namensbereich genannt. Das bedeutet wohl, dass in std nur die Namen mit doppeltem Unterstrich und die Namen mit Unterstrich und Großbuchstaben reserviert sind.
17.4.3.1 Abs. 1 S. 1
In der Version die mir vorliegt ist am 17.4.3.1.2, zweiter Spiegelstrich eine Fußnote 165, die besagt dass das auch für den NS std gilt, mit Verweis auf 17.4.3.1
§17.4.3.1, Abs.3 besagt "if the program deklares [...] a name in a context where it is reserved, [...] the behavior is undefined."
Die Frage ist jetzt, ob ein Programm dann ggf. von der Implementierung bereitgestellte Namen im Namensraum std überhaupt benutzen darf oder ob das auch schon undefined behavior ist.
bsp:
#include <somestdheader> //definiert void std::_somestdfunc() void std::_somestdfunc(); //Kein Verstoss gegen 17.4.3.1, abs 1., da keine Deklaration HUNZUGEFUEGT wird. Aber vllt. gegen die Fussnote 165? int main() { #ifdef _MY_COMPILER_THAT_DEFINES_SOMESTD_FUNC_IN_SOMESDT_HEADER_ std::_somestdfunc(); // undefined behavior?? #endif }
-
pumuckl schrieb:
Die Frage ist jetzt, ob ein Programm dann ggf. von der Implementierung bereitgestellte Namen im Namensraum std überhaupt benutzen darf oder ob das auch schon undefined behavior ist.
Das ist aus sich heraus klar. Da der betreffende Bezeichner überhaupt erst durch die Implementation eingeführt wird, kann der Standard schlecht eine Aussage über das Verhalten machen. Ergo ist das Verhalten undefiniert.
-
camper schrieb:
pumuckl schrieb:
Die Frage ist jetzt, ob ein Programm dann ggf. von der Implementierung bereitgestellte Namen im Namensraum std überhaupt benutzen darf oder ob das auch schon undefined behavior ist.
Das ist aus sich heraus klar. Da der betreffende Bezeichner überhaupt erst durch die Implementation eingeführt wird, kann der Standard schlecht eine Aussage über das Verhalten machen. Ergo ist das Verhalten undefiniert.
nicht impl. defined?
-
unskilled schrieb:
nicht impl. defined?
Muss die Implementation ihre eigenen Innereien dokumentieren? Ich glaube nicht.
Impl. defined ist etwas, dessen Existenz der Standard voraussetzt, und für das die Implementation ein bestimmtes dokumentiertes Verhalten haben muss. Beide Voraussetzungen sind für etwaige reservierte Bezeichner nicht erfüllt.
-
Scarabol schrieb:
Hi,
also verstehen tu ich den Text nicht, das ist mir zu theoretisch.
Wenigstens solltest du mal verstehen, was du tun musst, nicht unbedingt warum:
Bei Dingen wie:
vector<T>::iterator iter;wobei T ein Template-Typ ist, musst du immer
typename vector<T>::iterator iter;schreiben.
Oder, um es mal zu generalisieren:
[irgend::welche::Klassen::]Klasse<Template-Typ>::noch[::mehr::Klassen] oder Template-Typ::noch[::mehr::Klassen](das in eckigen Klammern muss dabei nicht vorkommen)
-
Ahhh!!
Wenn ichs nicht besser wüsste würde ich sagen ihr spinnt!

startable.h
#ifndef inc_startable_h #define inc_startable_h #include "irrlicht.h" #include "declarations.h" using namespace irr::gui; using namespace irr::core; namespace star { template <typename ITEM> class table { protected: class _line { typename list<ITEM>::Iterator type; list<stringw> _vars; }; public: table(gameengine *gm, IGUIElement *parent, list<stringw> columns); ~table(); void addline(typename list<ITEM>::Iterator type, list<stringw> _vars); void refresh(void); typename list<ITEM>::Iterator getactive(void); private: gameengine *_gm; IGUIElement *_parent; IGUIScrollBar *_scrollbar; IGUITab *_headline; IGUITab *_content; list<_line> _rows; typename list<_line>::Iterator _active; }; } #endifstartable.cpp
#include "gameengine.h" #include "startable.h" using namespace star; template <class ITEM> table<ITEM>::table(gameengine *gm, IGUIElement *parent, list<stringw> columns) { _gm = gm; _parent = parent; } template <class ITEM> table<ITEM>::~table() { }MfG
Scarabol
-
jetzt wirst du noch ein Problem haben - du kriegst vom Linker Fehlermeldungen zu "undefined references" - schau mal in der FAQ, da steht wieso

-
Mögliche Workarounds:
1. alles direkt in die Klassendefinition einfügen; das wird bei großen Templates ziemlich unübersichtlich
2. am Ende der Header-Datei eine Implementationsdatei inkludieren, in der die Member definiert werden (üblicherweise hat diese die Endung .impl)
3. die gewünschten Template-Instanzen explizit definieren
4. das Schlüsselwort export benutzen; allerdings gibt es kaum Compiler, die dieses unterstützen1. also alles in die .h Datei packen? Auch die Implementierung aus .cpp?
2. table.cpp in table.impl umbenennen und inkludieren?
3. Dann muss ich in table.cpp für alle (int, long, float, myclass, myclass2) explicit alle Memberfunktionen einzeln schreiben?
4. Wird das von Visual C++ 2010 unterstützt bzw. macht es Sinn das zu benutzen?MfG
Scarabol
-
Scarabol schrieb:
1. also alles in die .h Datei packen? Auch die Implementierung aus .cpp?
Alles, was Templates sind. Also die kompletten Definitionen von Klassen- und Funktionstemplates.
Scarabol schrieb:
2. table.cpp in table.impl umbenennen und inkludieren?
Ja. Du kannst auch .inl oder so als Endung nehmen. MSVC++ erkennt das als eigenen Dateityp.
Scarabol schrieb:
3. Dann muss ich in table.cpp für alle (int, long, float, myclass, myclass2) explicit alle Memberfunktionen einzeln schreiben?
Nein, du kannst nicht wirklich was Sinnvolles machen. Schreib das Template in den Header, und vieles wird gut.
Scarabol schrieb:
4. Wird das von Visual C++ 2010 unterstützt bzw. macht es Sinn das zu benutzen?
Nein und nein. Fast niemand unterstützt das Feature. Und diejenigen, die es tun, bereuen die verschwendete Implementierungszeit und die entstandenen Nachteile, bei gleichzeitig Null Vorteil. Im nächsten C++-Standard ist
exportGeschichte.
-
Hi,
Template in den Header schreiben, hab ich verstanden.
Was genau war nochmal das Template?
template <typename ITEM> // meinst du das mit Template?oder
table<ITEM>::table(gameengine *gm, IGUIElement *parent, list<stringw> columns) { _gm = gm; _parent = parent; }[EDIT]
Try&Error lieferte folgendes Ergebnis:#ifndef inc_startable_h #define inc_startable_h // this is my first template class so: LETS DO IT!!! #include "irrlicht.h" #include "declarations.h" using namespace irr::gui; using namespace irr::core; namespace star { template <typename ITEM> class table { protected: class _line { typename list<ITEM>::Iterator type; list<stringw> _vars; }; public: table(gameengine *gm, IGUIElement *parent, list<stringw> columns); ~table(); void addline(typename list<ITEM>::Iterator type, list<stringw> _vars); void refresh(void); typename list<ITEM>::Iterator getactive(void); private: gameengine *_gm; IGUIElement *_parent; IGUIScrollBar *_scrollbar; IGUITab *_headline; IGUITab *_content; list<_line> _rows; typename list<_line>::Iterator _active; }; template <class ITEM> table<ITEM>::table(gameengine *gm, IGUIElement *parent, list<stringw> columns) { _gm = gm; _parent = parent; } template <class ITEM> table<ITEM>::~table() { } } #endifMfG
Scarabol