PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : mehrdimensionale dynamische Arrays



farion
12-04-2007, 20:34
Hallo

gibt es so etwas wie "mehrdimensionale dynamische Arrays" in c++
Also

var[x][y][z][..]....

Wobei mir wichtig ist, dass das ganze beliebig geschachtelt und automatisch vergrössert werden kann und jede variable entweder Wert oder wieder array sein kann.

var[0] = 5;
var[1][0] = 67;
var[1][1] = 56;

Ganz schick wäre, wenn man sich nicht nur auf einen Typ, wie hier int beschränken muss, sondern beliebig den typ ändern kann.

var[0] = 10;
var[1] = "some text";

Wenn das ganze dann noch mapbar wäre - also:

var['nummer'] = 10;
var['street'] = "some text";

wäre ich überglücklich.

Ich habe schon gegoogelt und mir die container der stl angeschaut, allerdings habe ich noch nichts Geeignetes gefunden - allerdings bezweifle ich, dass ich der einzige bin, der sowas ganz praktisch fände.

Gruss far

locus vivendi
12-04-2007, 21:27
Das sind gleich einige Fragen auf einmal.


gibt es so etwas wie "mehrdimensionale dynamische Arrays" in c++
Also

var[x][y][z][..]....

Wobei mir wichtig ist, dass das ganze beliebig geschachtelt und automatisch vergrössert werden kann und jede variable entweder Wert oder wieder array sein kann.
Nein. Du kannst mit dem new Operator mehrdimensionale Arrays anlegen. Allerdings kann dabei nur die Größe einer Dimension (nämlich der ersten von links) variabel sein. Also z. B.
"new [x][100]", aber nicht "new [x][y]". Und die Größe verändern geht auch nicht.
Vielleicht kannst du ein Boost.MultiArray verwenden.


Ganz schick wäre, wenn man sich nicht nur auf einen Typ, wie hier int beschränken muss, sondern beliebig den typ ändern kann.

var[0] = 10;
var[1] = "some text";
Dazu müsstest du besondere Elemente in das Array stecken, die unterschiedliche Typen aufnehmen können. Oder einen speziellen Containertyp. Letzteres habe ich noch nie gesehen, aber die erste Option betreffend könntest du dir Boost.Any anschauen.


Wenn das ganze dann noch mapbar wäre - also:

var['nummer'] = 10;
var['street'] = "some text";

wäre ich überglücklich.
Dafür sollte Boost.MultiIndex geeigent sein.


Ich habe schon gegoogelt und mir die container der stl angeschaut, allerdings habe ich noch nichts Geeignetes gefunden
http://www.boost.org/
Dort unter "Documentation" solltest du mal stöbern. Allerdings glaube ich auch nicht so recht, dass es dort schon etwas Fertiges gibt, das alle dein Wünsche auf einmal befriedigen kann.

farion
13-04-2007, 22:38
Ich habe mittlerweile selber ein wenig rumprobiert und auch schon eine ganz ansehnliche Containerklasse geschrieben. Sie kann zumindest schonmal verschiede Variablentypen aufnehmen (keine beliebigen, sondern fest vorgegebene - aber das würde mir erstmal reichen) und dynamisch ist sie auch. Jetzt muss ich nur noch das mehrdimensionale und das mapping implementieren. Momentan habe ich noch ein paar Meinungsverschiedenheiten mit einigen überladenen operatoren. Ich werde das Ergebnis dann auf jedenfall mal hier posten.

boost werde ich mir mal anschauen, scheint ganz interessant zu sein.

Gruss far

farion
16-04-2007, 21:39
Ich habe gleich mal ne Frage: ich greife auf meine Elemente mittels [] zu, also überlade ich den operator[]

dynListElem& operator[](int index);

Das Problem ist jetzt, dass man ja einen nicht existenten index anfragen könnte.
Jetzt kann ich natürlich hergehen und in einem solchen Fall einfach ein neues Element mit dem index einfügen.

Das ist bei test[99] = 6; ja auch durchaus gewollt, bei cout << test[99] << endl; allerdings nicht - hier soll einfach nichts/0/"" zurückgegeben werden.
Kann ich irgendwie unterscheiden warum das Element geholt wird?
Ich möchte ein neues Element erzeugen, wenn ein schreibender Zugriff stattfindet, wenn nur ein lesender Zugriff stattfindet möchte ich kein neues Element anlegen.

Das ganze in Operatoren (=,+,<<,== etc.) zu machen geht ja nicht, da ja wenn diese Operatoren aufgerufen werden bereits das "vor" und "nach" dem Operator fertig sein muss.

Gruss Frieder

Yonibear
17-04-2007, 16:14
Du kannst auch einen const dynListElem& operator[](int index) const; definieren, der nur konstante Referenzen zurückgibt. Der Compiler sollte dann immer das größtmögliche const wählen, also die const& für den Lesezugriff und die nicht-const-Variante für den schreibenden Zugriff.

locus vivendi
17-04-2007, 20:09
Das ist bei test[99] = 6; ja auch durchaus gewollt, bei cout << test[99] << endl; allerdings nicht - hier soll einfach nichts/0/"" zurückgegeben werden.
Kann ich irgendwie unterscheiden warum das Element geholt wird?
Ich habe im Moment nicht viel Zeit, deshalb kann ich das nicht erklären, aber das geht im Prinzip über ein Proxy Objekt: Dein []-Operator liefert dabei nicht Objekte des eigentlich gespeicherten Typs zurück, sondern ein spezielles Objekt welches den Zuweisungsoperator so überlädt, dass dein Container nur dann verändert/vergrößert wird wenn diese Zuweisung ausgeführt wird.

Vielleicht schreibe ich später noch etwas dazu, und sonst schaust du vielleicht mal nach wie std::vector<bool>, funktioniert, dann kommst du vielleicht auf die Technik:
http://www.dinkumware.com/manuals/?manual=compleat&page=vector.html#vector<bool>
Speziell:
http://www.dinkumware.com/manuals/?manual=compleat&page=vector.html#vector<bool>

locus vivendi
17-04-2007, 20:10
Der letzte Link sollte natürlich der hier sein:
http://www.dinkumware.com/manuals/?manual=compleat&page=vector.html#vector<bool>::reference

farion
17-04-2007, 20:46
@Yonibear
Funktioniert das zuverlässig?

@locus vivendi
Also wenn ich das richtig verstanden habe, so liefert mein []-Operator dann dynListElemProxy oder so zurück.
Für diesen Typ überlade ich dann sämtliche Operatoren, bei den lesenden wird dann eben der Wert von dynListElem zurückgegeben und bei schreibenden wird dynListElem verändert. Also sone zwischen-Schicht, die das alles erstmal abfängt.
Hört sich nach viel Arbeit an, scheint aber plausibel.

bye far

farion
17-04-2007, 21:15
Okay, ich habe jetzt so eine Zwischenschicht, allerdings habe ich folgendes Problem:
Ich habe ungefähr Folgendes:

class dynList
{
class dynListElem{}
class dynListProxy{}
void add(int index);
dynListElem& get(int index);

dynListProxy& operator[](int index){
dynListProx *temp = new dynListProxy(index);
return temp;
}
}
dynList ist eine LinkedList von dynListElem-elementen. Wenn ich jetzt ein Element von meiner dynList mittels [] anfordere bekomme ich erstmal ein dynListProxy - dort werden dann die ganzen operatoren überladen und entsprechend entschieden was passieren soll.
Das Problem ist jetzt, dass ich dort (in dynListProxy) ja get() bzw. add() aufrufen muss. Ich habe versucht this mit an dynListProxy zu übergeben, aber das funktioniert nicht - wie kann ich aus dynListProxy auf meine Funktionen zugreifen?

edit: Ich habe noch ein Problem, und zwar beim Operator-Überladen:
Wenn jetzt mein Objekt vor dem Operator steht, also
<dynListProxy> = <int>;
so fange ich das mit

void dynListProxy& dynListProxy::operator(int& value);
ab.
Wenn es aber umgekehrt ist, habe ich Probleme. Also wenn ich einer int-Variable mein Objekt zuweise.

void int& int::operator(dynListProxy& value);
geht nicht - ist ja auch irgendwie klar, da int ja kein Objekt ist