Datenstruktur für Matrizen



  • Wenn ich gewusst hätte was meine Frage für Folgen hat.... 😮



  • Tja, das musst du jetzt ausbaden 😃
    Ist doch egal, man lernt immer was ...



  • Raspo wenn deine Einwände berechtigt wären dürfte man in Template-Klasse keine statischen Variablen benutzen.

    Gilt auch für Template-Funktionen (in Template-Klassen) mit statischen Variablen.

    Der Linker kann (muss es in oben genanntem Fall sogar) Duplikate durchaus erkennen.

    Edit:
    Das Inlining-Problem ist dadurch natürlich nicht behoben. Dazu muss man wie von David gezeigt den Compiler schon zwingen es nicht immer zu inlinen (wobei ich auch schon Funktionen in Template-Klassen direkt reingeschrieben habe und diese nicht geinlined worden).

    Wie gut der VC Linker Strippen kann müsste man mal testen.


  • Mod

    TomasRiker schrieb:

    Wenn jetzt der Linker kommt und A.obj und B.obj zu einer EXE zusammenlinkt, dann wird er aber doch nur die erste Instanzierung der Klasse nehmen und die andere verwerfen - oder nicht??

    der punkt ist (und mehr hab ich nicht behauptet) dass leute ohne es zu wissen trotzdem irgendwelche behauptungen aufstellen z.b. wird (nicht) geinlined... inlined ist schneller/langsammer und glauben ohne es je geprueft zu haben, was irgendjemand anders irgendwo irgendwie gehoert oder gelesen hat ueber templates.

    das resultiert darin dass (im gegensatz zu normalen klassen) das binary aufblaeht und am ende langsammer ist.

    du hast es hier den evolutionsschritt gut gezeigt 🙂

    nur leider die meisten anderen nicht. Ich behaupte nicht dass templates zu verteufeln sind, ich nutze sie selber seit vielen jahren und sage lediglich dass anfaenger damit mehr schlechtes als gutes anstellen.



  • Warst du denn nicht auch einer derjenigen, der ohne es zu wissen eine Behauptung aufgestellt hat? 🙂
    Ansonsten denke ich, können wir es dabei belassen und haben alle was gelernt ...


  • Mod

    TomasRiker schrieb:

    Warst du denn nicht auch einer derjenigen, der ohne es zu wissen eine Behauptung aufgestellt hat? 🙂

    dio mio, No.



  • Äh, sagtest du denn nicht, dass Methoden von Template-Klassen immer inline aufgerufen würden?

    Das könnte man ja denken, wenn man davon ausgeht, dass man Template-Klassen immer direkt an einem Stück mit allen Methoden angeben muss. Muss man aber nicht. Und dann macht es bei der Frage "inline oder nicht?" keinen Unterschied, ob es sich um eine Template-Methode handelt oder um eine normale.



  • Hier gibt's auch ne interessante Diskussion über Templates, Inlining und Code-Bloating:
    Klick


  • Mod

    TomasRiker schrieb:

    Äh, sagtest du denn nicht, dass Methoden von Template-Klassen immer inline aufgerufen würden?

    nein, ich sprach von templates und wie du oben am unterschied von klasse/template gesehen hast, wird das auch so gemacht. da ich deswegen schon 70MB binaries gesehen habe spreche ich auch nicht aufgrund von glauben/vermutung, sondern erfahrung.



  • Bin auch Befürworter von Vector<T, N> und Matrix<T, N, M>.

    Btw.:
    Darf man mal fragen ob ihr auch Color<N> oder sogar Color<T, N> habt ? 😉
    Vielleicht braucht man ja mal irgendwann eine Farbwert mit 5 oder 6 Channels ^^

    Könnte man nicht sogar die VertexFormate schön mit MPL hinbiegen? Um OnTheFly mit Typedefs sein eigenes VertexFormat definieren zu können.


  • Mod

    Pyr0kar schrieb:

    Darf man mal fragen ob ihr auch Color<N> oder sogar Color<T, N> habt ? 😉

    wieso nicht vector<T> dafuer nehmen?



  • Ja, ich habe für Farben ebenfalls das Vektor-Template genommen. Das war mitunter auch der Grund, warum ich das Template überhaupt erstellt habe - 2D-Vektoren für Texturkoordinaten, 3D für 3D halt 😉 und 4D u.a. für RGBA.



  • rapso schrieb:

    Pyr0kar schrieb:

    Darf man mal fragen ob ihr auch Color<N> oder sogar Color<T, N> habt ? 😉

    wieso nicht vector<T> dafuer nehmen?

    Ganz einfach, weil man bei einer eigenen Klasse so schöne dinge machen kann wie:

    static const Color3 White = Color3(255, 255, 255);
    static const Color3 Red= Color3(255, 0, 0);
    

    Bei XNA haben sie das auch, schreibt sich eigentlich dann ganz nett.
    Außerdem weiß man damit deutlicher dass es ein Farbwert ist.
    Niemand wird außerversehen eine Position als Farbwert behandeln u. andersrum 😉

    Oder eben 1, 1, 1 und 1, 0, 0 für die Werte - je nach Speicherung.
    Nebenbei: sollte man lieber chars zur speicherung benutzten um dann weiß als 255,255,255 darzustellen oder lieber floats die von 0 bis 1 reichen was ja opengl etc. dann annnimmt?


  • Mod

    Pyr0kar schrieb:

    rapso schrieb:

    Pyr0kar schrieb:

    Darf man mal fragen ob ihr auch Color<N> oder sogar Color<T, N> habt ? 😉

    wieso nicht vector<T> dafuer nehmen?

    Ganz einfach, weil man bei einer eigenen Klasse so schöne dinge machen kann wie:

    static const Color3 White = Color3(255, 255, 255);
    static const Color3 Red= Color3(255, 0, 0);
    

    was sollen diese zwei zeilen beweisen?

    Bei XNA haben sie das auch, schreibt sich eigentlich dann ganz nett.
    Außerdem weiß man damit deutlicher dass es ein Farbwert ist.

    hoe? was soll das aussagen? wo ist der unterschied zu

    typedef Vector<float,3> tyColor3;
    static const tdColor3 White(255, 255, 255);
    static const tdColor3 Red(255, 0, 0);
    

    ?

    Niemand wird außerversehen eine Position als Farbwert behandeln u. andersrum 😉

    der zusammenhang entgeht mir.

    Oder eben 1, 1, 1 und 1, 0, 0 für die Werte - je nach Speicherung.
    Nebenbei: sollte man lieber chars zur speicherung benutzten um dann weiß als 255,255,255 darzustellen oder lieber floats die von 0 bis 1 reichen was ja opengl etc. dann annnimmt?

    je nachdem ob du HDR unterstuetzung brauchst oder nicht.
    gibt ja viele wege nach rom, z.b.

    typedef Vector<Sat<float,0.f,1.f>,3> tyColor3;
    

    btw. opengl limitiert nicht auf 0 bis 1



  • rapso schrieb:

    Pyr0kar schrieb:

    rapso schrieb:

    Pyr0kar schrieb:

    Darf man mal fragen ob ihr auch Color<N> oder sogar Color<T, N> habt ? 😉

    wieso nicht vector<T> dafuer nehmen?

    Ganz einfach, weil man bei einer eigenen Klasse so schöne dinge machen kann wie:

    static const Color3 White = Color3(255, 255, 255);
    static const Color3 Red= Color3(255, 0, 0);
    

    was sollen diese zwei zeilen beweisen?

    Mir fällt leider jetzt erst auf dass die zwei Codezeilen wirklich nicht zeigen was ich meinte 😉 ^^
    Ich wollte eigentlich ausdrücken dass man das ganze der Klasse als Membervariable einbauen kann.
    So dass dann möglich ist:

    Color c = Color::White // eben noch mit templates etc.
    driver->clear(Color::White);
    

    Ansonsten (bei benutzung der vectoren für farben) muss man entweder sowas wie einen CommonColors-Namespace machen oder sonst was unschönes.

    rapso schrieb:

    Niemand wird außerversehen eine Position als Farbwert behandeln u. andersrum 😉

    der zusammenhang entgeht mir.

    Na der zusammenhang ist, dass bei z.b.

    Driver::clear(Color& color)
    

    Auch nur ein Color-Wert angegeben werden kann, wenn jemand da ein Vector reinhaut gibts ein netten compile-time-error. In Scott Meyers Effective C++ gibts einen Tipp der empfielt für sowas immer eigene Klassen zu schreiben damit der compiler schon zu compile-time weiß ob die Typen stimmen.
    Typedefs sind in C++ einfach nicht sicher.

    rapso schrieb:

    Oder eben 1, 1, 1 und 1, 0, 0 für die Werte - je nach Speicherung.
    Nebenbei: sollte man lieber chars zur speicherung benutzten um dann weiß als 255,255,255 darzustellen oder lieber floats die von 0 bis 1 reichen was ja opengl etc. dann annnimmt?

    je nachdem ob du HDR unterstuetzung brauchst oder nicht.
    gibt ja viele wege nach rom, z.b.

    typedef Vector<Sat<float,0.f,1.f>,3> tyColor3;
    

    btw. opengl limitiert nicht auf 0 bis 1

    danke, wusste ich nicht.

    Danke für deine antwort 🙂



  • Falls jemand langweilig ist, gleich noch ein paar Fragen:

    1. Macht eurer Meinung nach ein operator[] für Vector-Typen Sin? Bei irrlicht wurden die soweit ich weiß seit 1.3 rausgenommen - jemand eine idee?

    2. falls man sowas gefährliches wie operator[] mit Vector& (d.h. Referenz) rückgabe benutzt, sollte man dann im falle von einem falschen index eine exception werfen?
    Oder sollten vector-klassen frei von exceptions sein?

    Vector<T,N>& operator[](unsigned int n)
    {
    switch(n)
    {
    case 0: return X;
    case 1: return Y;
    default: //exception???
    }
    }
    

    3. Sollte die const-variante die keine Referenz, sondern einen Wert zurückgibt eine exception werfen oder lieber 0 rückgeben?

    Vector<T,N> operator[](unsigned int n) const
    {
    switch(n)
    {
    case 0: return X;
    case 1: return Y;
    default: //return 0    oder exception???
    }
    }
    

    4. Oder sollte man, wenn man wie ich std::tr1::array benutzt um die daten als union abzulegen:

    union
    			{
    				struct
    				{
    					T X;
    					T Y;
    				};
    				struct
    				{
    					std::tr1::array<T, 2> Elements;
    				};
    			};
    

    Dann lieber einfach so was nehmen ?

    T operator[](unsigned int n) const
    {
    return Elements[n];			
    }
    

    Fragen über Fragen, 😉 Antwortet wenn euch danach beliebt :p



  • Die letzte Variante, aber mit einem normalen Array (keine Ahnung, was std::tr1::array ist). Alles andere ist zu langsam. Höchstens im Debug-Build den Index checken (z.B. mit assert).


  • Mod

    Pyr0kar schrieb:

    rapso schrieb:

    Pyr0kar schrieb:

    rapso schrieb:

    Pyr0kar schrieb:

    Darf man mal fragen ob ihr auch Color<N> oder sogar Color<T, N> habt ? 😉

    wieso nicht vector<T> dafuer nehmen?

    Ganz einfach, weil man bei einer eigenen Klasse so schöne dinge machen kann wie:

    static const Color3 White = Color3(255, 255, 255);
    static const Color3 Red= Color3(255, 0, 0);
    

    was sollen diese zwei zeilen beweisen?

    Mir fällt leider jetzt erst auf dass die zwei Codezeilen wirklich nicht zeigen was ich meinte 😉 ^^
    Ich wollte eigentlich ausdrücken dass man das ganze der Klasse als Membervariable einbauen kann.
    So dass dann möglich ist:

    Color c = Color::White // eben noch mit templates etc.
    driver->clear(Color::White);
    

    bei c++ versucht man mit kapselung die member nicht direkt zugreifbar zu machen, das zu brechen mit static const ist zum einen nicht schoen, zum anderen musst du die definition noch ausserhalb schreiben... doppelt unschoen.

    auch aus diesem grund gibt es namespaces, so musst du grundlegende oop dinge nicht brechen und darfst sogar trotzdem ein packet schoen abkapseln... kanns ein dass es nur meine ansicht ist 🙂

    rapso schrieb:

    Niemand wird außerversehen eine Position als Farbwert behandeln u. andersrum 😉

    der zusammenhang entgeht mir.

    Na der zusammenhang ist, dass bei z.b.

    Driver::clear(Color& color)
    

    Auch nur ein Color-Wert angegeben werden kann, wenn jemand da ein Vector reinhaut gibts ein netten compile-time-error. In Scott Meyers Effective C++ gibts einen Tipp der empfielt für sowas immer eigene Klassen zu schreiben damit der compiler schon zu compile-time weiß ob die Typen stimmen.
    Typedefs sind in C++ einfach nicht sicher.

    dann scheint dir ziemlich viel in letzten paar jahren entgangen zu sein, sprachen wie cg/hlsl nutzen vectoren/colors als nur einen datentypen und beim normalen rechnen tag fuer tag macht man auch keinen unterschied, du kannst farben oder normalen in buffer stopfen und sie dann wieder auf der graphikkarten interpretieren wie du moechtest.

    ich hab zuhause meinen color4 von vector4 abgeleitet, sharen das meiste aber manches wie z.b. operator* ist dann anders.
    aber grundsaetzlich spricht aus meiner sicht nicht dagegen das meiste zu sharen.



  • Pyr0kar schrieb:

    union
    			{
    				struct
    				{
    					T X;
    					T Y;
    				};
    				struct
    				{
    					std::tr1::array<T, 2> Elements;
    				};
    			};
    

    Du kannst nur PODs in unions benutzen ⚠

    btw. ist das kein ISO-C++ aber die meisten Compiler unterstützen anonyme structs und unions.



  • lolz schrieb:

    btw. ist das kein ISO-C++ aber die meisten Compiler unterstützen anonyme structs und unions.

    weis eigentlich wer warum das so is!? mir fällt auf die schnelle eigentlich nix ein was gegen anonyme structs sprechen würd...


Anmelden zum Antworten