2012-04-01 4 views
2

Das Problem ist spezifisch, aber die Lösung offen Ende. Ich bin ein einsamer Programmierer, der versucht, einige Ideen mit einigen anderen Programmierern zu teilen.Eine Sammlung von benutzerdefinierten Strukturen (ein Wrapper) mit einem einzelnen Element (auch eine benutzerdefinierte Struktur) zu einer Auflistung der einzelnen Elemente

Ich habe einen Wrapper für eine Mathematikbibliothek. Der Wrapper stellt dem System eine konsistente Schnittstelle zur Verfügung, während ich Math-Bibliotheken für verschiedene Plattformen ein- und ausblenden kann. Der Wrapper enthält ein einzelnes Mitglied, also sagen wir für meine Matrix4x4-Wrapper-Klasse, dass es eine api_matrix_4x4-Struktur als einziges Mitglied des Wrappers gibt.

Meine aktuelle Zielplattform hat eine raffinierte wenig optimierte Bibliothek, mit ein paar dieser raffinierten Funktionen, die ein C-artiges Array des eingebetteten Wrappers benötigen, während meine Wrapper-Funktionen für diese mathematischen API-Funktionen dies nicht offen legen wollen Mitgliedstyp für den Rest des Systems. Wir haben also eine Sammlung von Wrappern (Verweis/Zeiger auf), die in die Funktion & der Mitglieder der Wapper in einer Sammlung innerhalb der Funktion benötigt werden, so dass sie an die Math-API übergeben werden können.

Ich bin überwiegend mit C++, einschließlich C++ 11 Funktionen, & kann auch C-Stil gehen. Idealerweise möchte ich eine No-Exception-Lösung, &, um so viele, wenn nicht alle dynamischen Zuordnungen zu vermeiden. Meine Wrapper-Funktionen können Standard-Bibliotheksarrays oder -Vektoren oder C-Style-Zeiger auf Arrays als Parameter verwenden, was auch immer intern erforderlich ist, nur kein dynamisches Casting (Run-Time Type Information).

1) Kann ich eine benutzerdefinierte Struktur/Klasse, die eine einzelne benutzerdefinierte Struktur enthält, in die benutzerdefinierte Struktur umwandeln? Wenn ja, wie wäre es, wenn es sich um eine Sammlung von Standardbibliotheken handelte? Ich denke hier an Typ-Slicing.

2) Würden Sie vielleicht eine Vorlage verwenden, um den an die Funktion übergebenen Typ zu maskieren, obwohl die Implementierung nur auf einen einzigen Typ (basierend auf der verwendeten math API) angewendet werden kann, oder wird die Verwendung von Vorlagen als schlecht angesehen?

3) Können Sie sich eine raffinierte Lösung vorstellen, vielleicht mit Swaps/Move Semantics/Emplacement? Wenn ja, bitte hilf mir, mir davon zu erzählen.

4) Oder bin ich resigniert zum Offensichtlichen, iteriere durch eine Sammlung, nehme das Mitglied heraus und benutze es für die API-Funktion?

Beispiel von dem, was ich von der Wrapper-Struktur & Wrapper-Funktion Unterschrift tue, & Beispiel dafür, was ich ist zu vermeiden versuchen Tun durch die Funktion Umsetzung gegeben:

struct Vector3dWrapper 
{ 
    API_Specific_Vector_3d m_api_vector_3d; 

    inline void operation_needing_vector_3d_wrappers(std::vector<Vector3d>& vectors) 
    { 
     // Now need a collection of API_Specific_Vector_3ds 
     try 
     { 
     std::Vector<API_Specific_Vector_3d> api_vectors; 
     api_vectors.reserve(vectors.size()); 
     for(auto vectors_itr = vectors.begin(); vectors_itr != vectors.end(); ++vectors) 
     { 
      // fill each Vector3d.m_api_vector_3d into api_vectors 
     } 
     } 
     catch(std::bad_alloc &e) 
     { 
     // handle... though in reality, try/catch is done elsewhere in the system. 
     } 



     // Signature is API_Multiply_Vectors_With_Matrix_And_Project(API_Specific_Vector_3d* vectors, size_t vector_count) 
     API_Multiply_Vectors_With_Matrix_And_Project(&api_vectors, api_vectors.size()); 
    } 

}; 
+2

Diese Frage deckt eher eine breite Palette von Themen ab. Könntest du etwas konkreter sein, mit einigen Beispielen? – leftaroundabout

Antwort

1
  1. Sie eine werfen kann Standard-Layout-Struktur (wie eine mit C kompatible Struktur) zu seinem ersten Mitglied, aber was ist der Sinn? Greifen Sie einfach auf das erste Mitglied zu und wenden Sie & an.

  2. Vorlagen ermöglichen normalerweise eine einheitliche Parametrisierung über eine Reihe von Typen. Sie können eine Vorlage schreiben, die nur einmal instanziiert wird, aber das scheint wiederum sinnlos. Was Sie wirklich wollen, ist eine andere Schnittstellenbibliothek für jede Plattform. Vielleicht könnten Vorlagen dabei helfen, gemeinsamen Code zu definieren, der zwischen ihnen geteilt wird. Oder Sie könnten das gleiche in Ebene C tun, indem Sie typedef s vor #include setzen.

  3. Lösung zu was? Die Standardkopie- und Verschiebungssemantik sollte für flache C-artige Strukturen mit Zahlen funktionieren. Wie bei tiefen Kopien müssen Sie, wenn die zugrunde liegenden Bibliotheken zeigerbasierte Strukturen haben, vorsichtig sein und alle benötigten Semantiken implementieren.Sicher ... einfach ... Standard ... "raffiniert" klingt dreckig.

  4. Nicht sicher, ich verstehe, was Sie mit Sammlungen tun. Sie meinen, dass jede Funktion erfordert, dass ihre Parameter zuerst in ein generisches Containerobjekt eingefügt werden? Constructing Container klingt teuer. Ihre Funktionen sollten die Funktionen in den zugrunde liegenden Bibliotheken so gut wie möglich parallelisieren.

+0

Vielen Dank. 1 ist nützlich zu wissen. Ich dachte, 2 würde mir diese einheitliche Parametrisierung erlauben, aber Sie haben Recht, die einzige Instanziierung, die es wenig mehr als eine Maske macht, die vielleicht in Ordnung ist für das, was ich brauche. Für 3 weiß ich, dass sie für flache C-Stil-Strukturen arbeiten, und keine Notwendigkeit für tiefe Kopien als keine Zeiger in Bezug auf das Mitglied. Zu 4, es ist nur 2 Funktionen von 25 ungerade Funktionen, dass die Mathe-API eine Sammlung von seinen Typen benötigt, die ich umgebe, um in übergeben zu werden. Ich möchte diese Typen nicht extern vom Wrapper aussetzen. – codey

+0

Für 3, ich denke, ich suchte nach "clever & effizient" Container + Typ Konvertierung Idiome/Tricks, obwohl Sicherheit wäre ein Anliegen. Vielleicht, von Kopf bis Kopf, etwas wie das Durchlaufen des Wrapper-Container-Parameters & cast + emplace in einen funktions-lokalen Wrapper-Member-Container. Nur Ideen wirklich. Math-Code muss relativ effizient sein, sonst könnte ich am Ende verschwenden, welche Optimierungen (SIMD-Anweisungen, neon, etc.) die API bietet, indem ich meine Wrapper-Typ-Sammlung zu API-Typ-Sammlung Konvertierung macht – codey

+0

@ codey Wenn die Plattformen potenziell einige schicke Optimierungen wie Vektorisierung, Sie müssen sehr vorsichtig sein, um Umwandlungen zu vermeiden, die den Optimierer verscheuchen könnten. Wirklich, der Compiler mag es, Dinge auf einfache und semantische Weise zu tun. Wenn Ihre Bibliothek aus ein paar typedefs und einlinigen Inline-Funktionen bestehen könnte, sollten Sie das tun. Wenn keine zugrunde liegende Funktion einen Containertyp benötigt und der Benutzer sie nicht benötigt, sollten Sie den zusätzlichen Aufwand berücksichtigen. – Potatoswatter