template als template übergeben?



  • Danke.
    Simon


  • Mod

    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.


  • Mod

    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
    }
    

  • Mod

    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?


  • Mod

    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;
    
    	};
    
    }
    
    #endif
    

    startable.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ützen

    1. 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 export Geschichte.



  • 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()
    	{
    	}
    
    }
    
    #endif
    

    MfG
    Scarabol


Anmelden zum Antworten