2016-04-07 4 views
0

Ich habe eine Template-Klasse myClass<T>, wobei T ein Skalar sein kann (float, int, double, etc.) Ich möchte ein vtkFloatArray schaffen, vtkIntArray oder vtkDoubleArray, je nach der Typ T.Nicht virtuelle Version von vtkDataArrayTemplate

Ich dachte, dass vtkDataArrayTemplate<T> wäre eine gute Lösung. Leider ist es eine virtuelle Klasse, so kann ich nicht schreiben:

vtkSmartPointer< vtkDataArrayTemplate<T> > array = vtkSmartPointer<vtkDataArrayTemplate<T> >::New(); 

, weil, wenn ich versuche, eine myClass zu instanziiert, ich den Fehler:

error: invalid conversion from ‘vtkObject*’ to ‘vtkDataArrayTemplate<float>*’ [-fpermissive]` 

Ich denke, es liegt daran, vtkDataArrayTemplate::New() existiert nicht (weil die Klasse virtuell ist), stattdessen wird vtkObject::New() aufgerufen. Dann verstehen wir, dass es nicht eine vtkObject in eine vtkDataArrayTemplate verwandeln kann.

Also meine Frage ist:

Gibt es eine nicht-virtuelle Version von vtkDataArrayTemplate, die mir vtkFloatArray zu schaffen erlauben würde, wenn T float ist, vtkDoubleArray wenn T double ist, usw.?

PS: Ich benutze VTK 6.0.0

Antwort

0

Eine E-Mail an die VTK-Benutzer-Mailingliste mich auch auf das half. Eine nützliche statische Funktion in vtkDataArray hat mir wurde:

vtkDataArray::CreateDataArray(int dataType) 

Es ermöglicht ein Datenfeld vom Typ Datentyp zu erstellen.

nun die Template-Parameter T in einen VTK Typ zu verwandeln, ich den Code habe ich in diesem other post erwähnt: (danke norisknofun)

#include <vtkType.h> 

int GetVTKType(std::size_t hash_code) 
{ 
    static std::map<std::size_t, long> typeMap; 
    if(typeMap.empty()) 
    { 
     typeMap[typeid(void).hash_code()]    = VTK_VOID; 
     typeMap[typeid(char).hash_code()]    = VTK_CHAR; 
     typeMap[typeid(signed char).hash_code()]  = VTK_SIGNED_CHAR; 
     typeMap[typeid(unsigned char).hash_code()]  = VTK_UNSIGNED_CHAR; 
     typeMap[typeid(short).hash_code()]    = VTK_SHORT; 
     typeMap[typeid(unsigned short).hash_code()]  = VTK_UNSIGNED_SHORT; 
     typeMap[typeid(int).hash_code()]    = VTK_INT; 
     typeMap[typeid(unsigned int).hash_code()]  = VTK_UNSIGNED_INT; 
     typeMap[typeid(long).hash_code()]    = VTK_LONG; 
     typeMap[typeid(unsigned long).hash_code()]  = VTK_UNSIGNED_LONG; 
     typeMap[typeid(float).hash_code()]    = VTK_FLOAT; 
     typeMap[typeid(double).hash_code()]    = VTK_DOUBLE; 
     typeMap[typeid(std::string).hash_code()]  = VTK_STRING; 
     typeMap[typeid(long long).hash_code()]   = VTK_LONG_LONG; 
     typeMap[typeid(unsigned long long).hash_code()] = VTK_UNSIGNED_LONG_LONG; 
     typeMap[typeid(int64_t).hash_code()]   = VTK___INT64; 
     typeMap[typeid(uint64_t).hash_code()]   = VTK_UNSIGNED___INT64; 
    } 
    return typeMap[hash_code]; 
} 

So ist der endgültige Code lautet:

vtkDataArray *array = 
    vtkDataArray::CreateDataArray(GetVTKType(typeid(T).hash_code())); 
0

der gleichen Logik des anderen VTK Nach question können Sie eine Fabrik mit einer Karte des Typs machen

std::map< vtktypes , std::function< void*() > > _map; 

std::function< void*() > zielt darauf ab, ein einfach zu sein Objekt Schöpfer, void* Rückkehr, die dann statisch in den Zieltyp gegossen werden muss.

mag:

_map[VTK_INT] = [](){ return new vtkFloatArray(); } 
+0

vtk-users sagte mir, dass diese Karte zwischen VTK-Typ und Aufruf der rechten Funktion existiert, und es ist in 'vtkDataArray :: CreateDataArray (int dataType)'. – matthieu