Variabler Vektor
-
Hallo zusammen,
ich spiele gerade mal wieder ein bischen rum und versuche mir einen variablen Vektor (Mathematik) zu schreiben. Hier mal was ich bisher habe:
template<class Type, int Number> class Vector { public: Vector(){}; Vector(Type data[Number]) { for (int i = 0; i < Number; ++i ) { itsData[i] = data[i]; } } const Type& at(int i) const { return itsData[i]; } void operator+= (const Vector<Type, Number>& v) { for (int i = 0; i < Number; ++i) { itsData[i] += v.itsData[i]; } } void operator-= (const Vector<Type, Number>& v) { for (int i = 0; i < Number; ++i) { itsData[i] -= v.itsData[i]; } } private: Type itsData[Number]; };Bin damit aber irgendwie noch nicht so ganz zufrieden, insbesondere mit dem Konstruktor. Ich weiß nicht so genau wie man eine Zuweisung effizient lösen könnte. Auch mit dem Addieren und Subtrahieren bin ich nicht zufrieden, wie könnte ich z.B. nur Additionen zulassen bei denen die Vektoren die gleiche Anzahl Spalten/Zeilen haben? Kann mir von Euch jemand vielleicht ein wenig auf die Sprünge helfen? Vielen Dank schon mal.
Gruß
Patrick
-
die Addition so wie du sie hast, läuft doch nur mit vektoren die gleichen typs (==gleicher datentyp und anzahl zeilen). Andere Vektoren können nicht in Vektor<Type, Number> konvertiert werden. Den Konstrktor könntest du mit std::copy machen. Wenn du da allerdings objekte hast die viel speicher benötigen wird das Kopieren ne weile dauern. Kannste aber nicht ändern, denn die Objekte müssen ja auch im speicher des Vektors sein.
Vektor::Vektor(Type data[Number]) { std::copy(data, data+Number, itsdata); }
-
Was ich gerne machen möchte, ist z.B. sowas
Vector<int, 3> myVector(1, 1, 1);. Weiß aber nicht wie ich das umgesetzt bekomme.
Gruß
Patrick
-
a) Soweit ich weiß, gibts ne Möglichkeit, Funktionen mit variabler Parameterzahl zu definieren:
func(int i1, ...);oder so ähnlich. Müsstest mal nachschauen, wie das umzusetzen ist. Allerdings kannst du so nicht überprüfen, ob der User die richtige Anzahl an Parametern angegeben hat (ggf. einfach abschneiden oder mit Nullen auffüllen). Ich bin mir außerdem nicht sicher, ob sowas für Konstruktoren erlaubt ist.
b) Spezialisiere das Template für sagen wir mal Number <=10, da es für größere Zahlen immer unwahrscheinlicher wird, dass da jemand jede einzelne Komponenten von Hand aufzählen wird.
Die 10 Spezialisierungen lassen sich denke ich mal lässig über ein kleines Skript ausführen, das sie schreibt. (Oder du machst es per Copy&Paste, dann wünsche ich allerdings viel Spaß, wenn du an dem Konstruktor mal was entscheidendes ändern willst...)
-
uh... das so zu haben ist schwer... mit den neuen Sequence-konstruktoren in c++0x ginge das wohl, aber so...
vielleicht kann man da mit metaprogrammierung was machen? keine Ahnung. Aber du kannst zB versuchen mit boost::assign einen std::vector mit dem inhalt zu erstellen und den dann an den konstruktor zu übergeben.
-
Es macht meist Sinn Vektoren für Dimensionen bis 4 zu spezialisieren.
Dann musst du bloss noch gucken dass alle Funktionen der nicht spezialisierten Version (>4 Dimensionen) auch in den Spezialisierungen <= 4 Dimensionen vorhanden sind.
Somit ist der Vektor generisch verwendbar (über das immer vorhandene Subset der nicht spezialisierten Version), aber man kann in den "üblichen Fällen" (eben <= 4 Dim.) "schön" arbeiten, also z.B. die Werte alle im ctor angeben etc.
-
@Pacosys: Ein komplettes Beispiel ist hier
http://www.oop-mit-cpp.de/cppbuch/k9/vektor/
im Zusammenwirken mit
http://www.oop-mit-cpp.de/cppbuch/k9/mathvek/
zu finden. Wie es funktioniert, kann man in
http://www.oop-mit-cpp.de/kap9.pdf, Abschnitt 9.2 sehen.