Gdy w C++ tworzymy typ wymagający indeksowania więcej niż jednym indeksem – a więc coś w stylu wielowymiarowej tablicy, np. macierzy – zazwyczaj używa się do tego celu operatora nawiasów okrągłych. Nie jest to specjalnie spójne z tablicami wbudowanymi język, gdzie do indeksowania stosuje się nawiasy kwadratowe, w tym przypadku nawet więcej niż jedną parę.
O ile jednak da się przeciążyć operator []
, o tyle “operatorów” [][]
, [][][]
, itd. już nie. Można jednak zastosować inną technikę, jeśli chcemy by nasze własne typy były składniowo maksymalnie podobne do wbudowanych.
Trzeba mianowicie przygotować je tak, by dało się do nich stosować operator []
niejako więcej niż raz. Wymaga to wprowadzenia jakiejś klasy pośredniej; dla macierzy może ona reprezentować pojedynczy wiersz:
Dla tego wiersza piszemy naturalnie zwykły operator indeksowania, pozwalający nam dostać się do jego elementów. Trik leży w postaci operatora, którą umieszczamy w samej klasie macierzy:
Zwraca ona nasz wiersz, a właściwie jego opakowanie, które to zdefiniowaliśmy. W ten sposób osiągamy dla Matrix<T>
zachowanie niemal dokładnie analogiczne do tablic typu T**
: pierwsza para nawiasów daje nam T*
(u nas MatrixRow<T>
), zaś druga konkretną wartość typu T
:
W tym rozwiązaniu oczywiście parę szczegółów do uwzględnienia (np. warianty const
naszego operatora). Widać jednak, że jeśli bardzo chcemy, to przy odrobinie pomysłowości da się wszędzie używać “właściwych” nawiasów :)
Fajny sposób ;) Co prawda niekoniecznie przydatny, ale…
Pytanie co z wydajnością? Ja generalnie nie wierzę w optymalizacje kompilatora i wątpię, żeby wyszedł z tego kod równie szybki, co z przeładowanego w macierzy operatora () (int row, int col).
Nie wiem czy najpierw powinno się zwracać wiersz czy kolumnę ale to inny problem ^^
@lukaszw: Nie wiem czy nieprzydatny. Może przy grach komputerowych mniej przydatny, ale jak najbardziej stosowany. Kiedyś już coś podobnego gdzieś widziałem w użyciu i działało jak powinno.
@Reg: w takim wypadku trzeba sie zapytac raczej czy wygoda uzycia zrekompensuje male straty w szybkosci ^^