2016-06-17 6 views
1

Ich suche in die Matrix-Klassenbibliothek Eigen und der docs Zustand, dass eine Klasse Matrix Vorlage kann unter Verwendung der folgenden Template-Parameter instanziiert werden:Wie kann die Speicherzuweisung in Abhängigkeit von den Vorlagenparametern gesteuert werden?

Matrix<typename Scalar, int RowsAtCompileTime, int ColsAtCompileTime> 

wo Scalar die Art der Matrix-Koeffizienten (Doppel, float, Int, komplex, etc ...). RowsAtCompileTime und ColsAtCompileTime sind die Matrix-Dimensionen.

Zum Beispiel eine 4x4 Matrix von Schwimmern instanziert werden könnte wie folgt aussehen:

Matrix<float, 4, 4> matrix; 

Die Eigen docs Zustand, dass im vorherigen Fall, da die Zeilen bei der Kompilierung bekannt sind, und für „kleine "Matrizen, Speicher für die Matrix-Elemente ist statisch zugeordnet.

Allerdings, wenn Sie Speicher dynamisch zuzuweisen wählen (für große Matrizen oder weil Sie nicht wissen, bei der Kompilierung der Anzahl der Zeilen und Spalten), können Sie die folgende Vorlage Instanziierung verwenden, die dynamisch Speicher zuweisen werden:

Meine Frage ist, wie wird dies konzeptionell mit dem C++ - Template-Mechanismus erreicht? Da ich mich hauptsächlich für die C++ - Techniken interessiere, die dazu verwendet werden, könnte mir bitte ein kurzes Beispiel mit einem Stack-Typ geben, bei dem die Speicherzuweisung auf ähnliche Weise gesteuert wird? Vielen Dank!

Antwort

3

Die Vorlage wird teilweise spezialisiert, um die verschiedenen Zuordnungen zu behandeln. Kurz gesagt,

template <typename T, int N> 
struct Vector { 
    T data[N]; 
}; 

static const int Dynamic = -1; 

template <typename T> 
struct Vector<T, Dynamic> { 
    T* data; 
}; 

eindeutig ein großer Teil der Schnittstelle ist in diesem Beispiel fehlt, aber das unterstreicht die wichtige Rolle der Mechanik der Template-Spezialisierung sowie die Einzelheiten des unterschiedlichen zugrunde liegenden Speichers. Der Konstruktor (in der Spezialisierung) würde die dynamische Zuweisung durchführen.

In der Praxis könnte man die Details des Speichers auf eine VectorStorage<T, Rows, Cols> verschieben, die teilweise spezialisiert ist. Die Vector würde enthalten ein Element dieses Typs (richtig instanziiert seine eigenen Parameter verwendet wird) und ein großer Teil der Schnittstelle würde nur einmal ...

umgesetzt werden
template <typename T, int N> 
struct VectorStorage { 
    VectorStorage(const size_t) {} 
    T data[N]; 
}; 

static const int Dynamic = -1; 

template <typename T> 
struct VectorStorage<T, Dynamic> { 
    VectorStorage(const size_t n) : data(new T[n]) {} 
    ~VectorStorage() { delete[] data; } 
    // define copy ops, etc. 
    T* data; 
}; 

template <typename T, int N> 
class Vector { 
    public: 
    Vector(const size_t n) : storage(n) {} 

    T operator[](const size_t i) const { return storage.data[i]; } 
    // etc. 

    private: 
    VectorStorage<T,N> storage; 
}; 
+0

Vielen Dank für Ihre Antwort und hilft mir dies herauszufinden! Ich denke, es gibt einen leichten Tippfehler in Ihrer Antwort: operator [] in Vector soll T zurückgeben und nicht int korrekt? – BigONotation

+0

@BigLudinski Korrekt. Ich werde das reparieren. – Andrew

Verwandte Themen