operator[][]?



  • Kann man in einer Klasse die ein 2D-Feld verwaltet den operator[][] erzeugen, um wie mit einem normalen 2D-Feld zu arbeiten?



  • Nein, aber du kannst den operator[] ein Objekt einer Klasse zurückgeben lassen, die ein eindimensionales Array darstellt und wieder einen Operator[] zur Verfügung stellt.



  • hätte mich auch interessiert.. gibts den operator[][] überhaupt??
    grüße



  • Nein. Es gibt nur den [] - operator.



  • @GPC: Ich mag Deine Signatur. 🙂

    @|M|: In diesem Fall bietet es sich IMHO an, nicht den op[] zu überladen sondern op() mit zwei Parametern. Das entspricht meist eher der ursprünglichen mathematischen Schreibweise und ist im Zweifelsfall (manchmal) schneller.



  • Konrad Rudolph schrieb:

    @GPC: Ich mag Deine Signatur. 🙂

    😉



  • Wenn du ein zweidimensionales Array hast würde ich es als Programmierer am logischsten finden, wenn der []-Operator zwei Parameter nimmt. Also sowas wie field[x, y] = value. Das geht in C++ sicherlich auch oder?



  • Optimizer schrieb:

    Das geht in C++ sicherlich auch oder?

    Nein, leider nicht. Daher ja op() als Ersatz.



  • Achso, schade.



  • naja, ob man nun den index operator ode den klammer operator nutzt ist reine gewöhnugssache.
    ersteren kann man halt nicht überladen. Matrizen sind aber schnell selbst geschrieben und gut geeignet um den vorteilvon templates und evtl sogar inline kennen zu lernen. zudem kann man mit keinen testes auch sehen, dass der schleifendurchlauf hier auch eine performance rolle spielt, wenn du die matrix z.B. auf einen vector abbildest. denn entweder herrscht eine höhere datenlokalität bezgl der spalten oder der reihen, je nachdem wie du den indexer wählst, welchen man z.B. als template argument mit übergeben koennte.
    nur so am rande 😉

    in C# siehst gibt es auch diverse mehrfelder klassen. jagged arrays...



  • besser, man gibt ein proxy-objekt zurück.

    Proxy Array::op[](int y){
      return Proxy(this,y);
    }
    ...
    double Array::Proxy::op[](int x){
       return m_array->at(m_y,x);
    }
    

    dann kann man at(y,x) mit allen schikanen implementieren. selbst als hashtable für ganz dünn besetzte matrizen. und der kram für op[][] bleibt unwichtige nebensache und verwirrt keinen.



  • muffmolch schrieb:

    naja, ob man nun den index operator ode den klammer operator nutzt ist reine gewöhnugssache.
    [...]
    in C# siehst gibt es auch diverse mehrfelder klassen. jagged arrays...

    Eben, Jagged Arrays sind aber konzeptionell etwas total anderes als Matrizen. Letztendlich ist es nicht so wichtig aber ich finde eine visuelle Trennung zwischen einem Matrix-Konzept und einem Jagged Array schon ganz nett und daher bietet es sich an, beim Zugriff auf ein Element zwischen dem Array-Zugriff '(i, j)' und dem Zugriff auf geschachtelte Fehlder '[i][j]' zu unterschieden.



  • Konrad Rudolph schrieb:

    muffmolch schrieb:

    naja, ob man nun den index operator ode den klammer operator nutzt ist reine gewöhnugssache.
    [...]
    in C# siehst gibt es auch diverse mehrfelder klassen. jagged arrays...

    Eben, Jagged Arrays sind aber konzeptionell etwas total anderes als Matrizen. Letztendlich ist es nicht so wichtig aber ich finde eine visuelle Trennung zwischen einem Matrix-Konzept und einem Jagged Array schon ganz nett und daher bietet es sich an, beim Zugriff auf ein Element zwischen dem Array-Zugriff '(i, j)' und dem Zugriff auf geschachtelte Fehlder '[i][j]' zu unterschieden.

    auf jeden fall! zumal jagged arrays i.d.R. langsamer sind (hab diesbezueglich mal eine Studienarbeit schreiben lassen, die den performance unterschied zwischen c++ und c# testen sollte, auf der c# seite sollte auch die performance der verschiedenen array strutkuren getestet werden. und überraschender weise waren die jagged damals glaub schneller. was er auch begründen konnte. war damals noch des .NET framework 1.0... (die arbeit kann man von meiner homepage zihen)



  • Optimizer schrieb:

    Wenn du ein zweidimensionales Array hast würde ich es als Programmierer am logischsten finden, wenn der []-Operator zwei Parameter nimmt. Also sowas wie field[x, y] = value. Das geht in C++ sicherlich auch oder?

    Das Problem ist nur, dass es in C++ eigentlich gar keine mehrdimensionalen Arrays gibt. Insofern ist es auch nicht verwunderlich, dass op[] nur einen Parameter nimmt.



  • groovemaster schrieb:

    Optimizer schrieb:

    Wenn du ein zweidimensionales Array hast würde ich es als Programmierer am logischsten finden, wenn der []-Operator zwei Parameter nimmt. Also sowas wie field[x, y] = value. Das geht in C++ sicherlich auch oder?

    Das Problem ist nur, dass es in C++ eigentlich gar keine mehrdimensionalen Arrays gibt. Insofern ist es auch nicht verwunderlich, dass op[] nur einen Parameter nimmt.

    Der operator[] heißt meines Wissens nach "eckige-Klammern-Operator" oder "Index-Operator". Je nachdem was man damit indiziert, kann ich mir sehr gut vorstellen, dass ein solcher Operator mehrere Parameter nimmt. Ein so ein Fall wäre ein mehrdimensionales Array. Es gibt spätestens dann eins, wenn ich eins baue...

    Letztens hab ich mir sowas gebaut:

    public Cell this[int layer, int x, int y] { get; set; }
    public Cell this[int layer, Vector pos] { get; set; }
    

    Und fand ich in meinem Kontext voll ok. Denn es gibt schlichtweg ein mehrschichtiges, zweidimensionales Terrain bei mir.



  • Optimizer schrieb:

    groovemaster schrieb:

    Optimizer schrieb:

    Wenn du ein zweidimensionales Array hast würde ich es als Programmierer am logischsten finden, wenn der []-Operator zwei Parameter nimmt. Also sowas wie field[x, y] = value. Das geht in C++ sicherlich auch oder?

    Das Problem ist nur, dass es in C++ eigentlich gar keine mehrdimensionalen Arrays gibt. Insofern ist es auch nicht verwunderlich, dass op[] nur einen Parameter nimmt.

    Der operator[] heißt meines Wissens nach "eckige-Klammern-Operator" oder "Index-Operator". Je nachdem was man damit indiziert, kann ich mir sehr gut vorstellen, dass ein solcher Operator mehrere Parameter nimmt. Ein so ein Fall wäre ein mehrdimensionales Array. Es gibt spätestens dann eins, wenn ich eins baue...

    Das mag ja für C# so funktionieren, aber in C++ wird dir kein Index-Operator mehrere Parameter entgegennehmen - im Ausdruck arr[x,y] werden die beiden Werte über den Komma-Operator miteinander verknüpft, so daß der op[] letztlich nur das y zu sehen bekommt (du könntest natürlich op, überladen, aber dann kannst du nicht mehr mit reinen int-Werten hantieren - arr[Index(x),y] wäre legal und womöglich eine Alternativ zu volkards Proxy-Ansatz).



  • Ich habe das ganze mal unter linux mit dem gcc 3.4.6 und 4.1.1 getestet.

    #include "iostream"
    using namespace std;
    
    class Test
    {
    	public:
    		void operator [](int a, int b) {
    			cout<<"a: "<<a<<" ,b: "<<b<<std::endl;
    		}
    };
    
    int main()
    {
    	Test t;
    	t [10 , 5];
    	return 0;
    }
    

    beim übersetzen schmeisst der gcc folgende Fehlermeldungen:

    main.cpp:7: error: 'void Test::operator[](int, int)' must take exactly one argument

    ergo scheint es, das sowas nicht mit C++ geht. Man müsste in den Standard schauen um gewissheit zu haben.



  • Ich weiß jetzt nicht, ob das hier erlaubt ist mache aber erstmal trotzdem

    13.5.5 1 Subscripting
    operator[] shall be a nonstatic
    member function with exactly one parameter. It implements the subscripting syntax
    postfix-expression[ expression ]
    Thus, a subscripting expression x[y] is interpreted as x.operator[](y) for a class object x of type T
    if T::operator[](T1) exists and if the operator is selected as the best match function by the overload
    resolution mechanism (13.3.3).



  • a.at(y,x) und da gibt es überhaupt gar keinen grund mehr, verwirrende weil unübliche schnittstellen zu denken.

    und der aufruf cout<<a[3,4]-a[2,3] funktioniert wegen des kommaoperators und bewirkt nix anderes als cout<<a[4]-a[3] (und gibt mir die breite der matrix aus). ihr wollt hoffentlich nicht, daß meine wunderschönenen programme abstürzen, weil cout<<a[3,4]-a[2,3] auf einmal sowas wie cout<<a[3][4]-a[2][3] macht.



  • volkard schrieb:

    und der aufruf cout<<a[3,4]-a[2,3] funktioniert wegen des kommaoperators

    Idee, Idee! Man führt einfach einen Proxy 'i' (für 'index') ein und überlädt den Komma-Operator sinnvoll. Dann kann man schreiben

    cout << a[i(3), i(4)] // oder auch das zweite 'i' weglassen:
         << a[i(3), 4];
    

    Und heraus kommt dasselbe wie bei 'a.at(3, 4)'.

    🙂

    Ein Schelm, wer Böses dabei denkt. (So ähnlich habe ich übrigens mal ein "echtes" param-array für C++ implementiert.)

    /EDIT: Und damit man das 'i' nach wie vor in Zählschleifen verwenden kann, packt man den Proxy natürlich in einen eigenen Namensbereich und schreibt dann immer

    cout << a[custom::helpers::matrix::indexing::i(3), 4];
    

Anmelden zum Antworten