Template Parameter bestimmt Anzahl der Funktionsparameter
-
Ich hab mal ein wenig herumgespielt, folgendes ist ein wenig umständlich, ich weiß nicht wie gut Compiler das weg-optimieren können und die doppelte Typ-Angabe ist umständlich; sonst find ich's aber schön :):
template<typename T, unsigned int Size> class array_n { private: template<unsigned int CurSize> struct MakeList { MakeList( T* t ) { for ( int i=0; i<CurSize-1; ++i ) elems[i] = t[i]; } MakeList<CurSize+1> operator()( T t ) { elems[CurSize-1] = t; return MakeList<CurSize+1>( &elems[0] ); } int elems[CurSize]; }; template<> struct MakeList<1> { MakeList( T t ) : elem(t) { } MakeList<2> operator()( T t ) { return MakeList<2>( &elem ); } int elem; }; public: typedef MakeList<1> Dims; public: array_n( const MakeList<Size>& dims ) { } }; void main() { array_n<int,4> a( array_n<int,4>::Dims(1) (2) (3) (4) ); }Das Konzept ist an boost::list_of angelehnt.
-
Shade Of Mine schrieb:
Natuerlich ist das Array in eine Klasse gekapselt. Das ist ja der Sinn der Sache. Du schreibst
array_n<int, 3> arr(1,2,3); arr[0][0][0]=7;und fertig. array_n ist auch so clever nur eine allokation zu machen...
Abgesehen davon, daß du nicht die Konstruktorschreibweise benutzen kannst, dürfte das mit meiner Variante durchaus umsetzbar sein. ([] finde ich für Array-Dimensionen ohnehin intuitiver.)
Badestrands Version ist eigentlich genau das gleiche, nur mit () anstatt [].
-
ich bin fast sicher, Shade will hochdimensionale arrays als hashtables abspeichern, wobei beim zugriff dann einfach die indizes gehasht werden und als ersten suchkey genommen werden. vielleicht hat er auch keine lust und nimmt innendrin eine std::multimap.
aber bestimmt baut er keine echten 8-dimensionalen arrays, so ein winziges achtdimensionales int[13][16][25][22][13][24][16][24] braucht nämlich schon 51 terabyte. nichtmal ein mac hat so viel speicher. ich bezweifle daher, daß das rekursive aufbauen des arrays sachdienlich ist, und hab ihm die parameter als array in die hand gegeben.
-
volkard schrieb:
aber bestimmt baut er keine echten 8-dimensionalen arrays, so ein winziges achtdimensionales int[13][16][25][22][13][24][16][24] braucht nämlich schon 51 terabyte.
Ungefähr dahin zielte mein Beispiel

volkard schrieb:
ich bezweifle daher, daß das rekursive aufbauen des arrays sachdienlich ist, und hab ihm die parameter als array in die hand gegeben.
Genau das tut meine Lösung auch. Ob man nun das Array im operator T********() anhand dieser Liste konstruiert oder ob die Array<T,Dim>-Klasse einen Konstruktor für ArrayCreator<T,Dim>-Objekte definiert und dort anhand von ArrayCreator<T,Dim>::sizeArray den benötigten Speicher alloziert, ist prinzipiell unerheblich.
-
array_n<int,4> a( array_n<int,4>::Dims(1) (2) (3) (4) );Das existiert mit Hilfe von inline_containern bereits. Aber danke

@volkard:
In der Tat gibt es 2 Varianten:
array_n<> dass ein mehrdimensionales array auf einem eindimensionalen abbildet. Das eignet sich natürlich nur für kleine größen. Aber dafür finde ich es unheimlich praktisch. Vorallem da duarray<int, 3> arr(1,2,3); foo(arr[0].begin(), arr[0].end());machen kannst.
Und es gibt ein multi_array<> das das ganze per std::map löst (wobei mir die implementierung noch nicht so gefällt - ich bin da eher erst am interface dran).
Das bietet natürlich größere mehrdimensionale arrays aber man kann nicht über eine dimension iterieren. aber multi_array ist noch nicht fertig. array_n dagegen verwende ich schon.
-
audacia schrieb:
Badestrands Version ist eigentlich genau das gleiche, nur mit () anstatt [].
Ups, das war mir nicht klar, jetzt sehe ich's aber auch

Shade Of Mine schrieb:
dann setzt die sichere variante halt einfach wirklich variadic templates voraus - wer das nicht hat muss mit der unsicheren variante mit laufzeitfehlern leben...
Was spricht denn bei der "unsicheren" Variante gegen audacias/meine/deine-inline-container Lösung?
-
Badestrand schrieb:
Was spricht denn bei der "unsicheren" Variante gegen audacias/meine/deine-inline-container Lösung?
Sieht hässlich aus.
Es geht hier nur um reine Ästhetik - die Funktionalität ist ja bereits vorhanden. Die variadic Template Variante ist zB sehr schön.
-
Shade Of Mine schrieb:
Badestrand schrieb:
Was spricht denn bei der "unsicheren" Variante gegen audacias/meine/deine-inline-container Lösung?
Sieht hässlich aus.
Es geht hier nur um reine Ästhetik - die Funktionalität ist ja bereits vorhanden. Die variadic Template Variante ist zB sehr schön.
Dann spezielisier den ctor für Dimensionszahlen bis vielleicht 4 oder 5. Oder gleich 10.
Die hässliche Variante kannst du dann immer verwenden, und bei "normalen" Arrays auch die schönere.So würde ich es zumindest machen. Wenn dann variadic templates mal kommen kann man ja jederzeit die Implementierung anpassen, so dass die "schöne" Version mit allen Dimensionszahlen verwendet werden kann - der Client-Code ändert sich dadurch ja nicht.
-
Shade Of Mine schrieb:
Sieht hässlich aus.
Zumindest mit eckigen Klammern ist das recht nah an der üblichen Syntax für Array-Deklarationen. Was ist da häßlich?
Ansonsten befolge hustbaers Vorschlag.
-
p.S.: ich finde üble Code-Wiederholung, wie sie für die erwähnte Spezialisierung nötig wäre, bzw. den grenzwertigen Einsatz von Makros mit dem man es auch machen kann, zwar nicht schön, aber in Library-Code durchaus vertretbar. Nämlich wenn sich dadurch für den User-Programmer Vorteile ergeben.
In dem Fall wäre das ja so, und daher fände ich es auch OK.