2016-04-07 8 views
0

VTK hat typedefs für Basistypen (float, int, double usw.) und weist eine Zahl pro Typ zu. Sie sind here angegeben. Die Funktion GetDataType(), zum Beispiel vtkDataArray, gibt eine Ganzzahl zurück, die einem der Typen entspricht. Ich möchte diese Ganzzahl mit den grundlegenden Datentypen (float, int, double) vergleichen.Vergleichen von VTK-Datentypen und Basisdatentypen

Gibt es eine Möglichkeit, dies einfach zu tun?

Die Verwendung, die ich davon habe, ist eine Vorlagenklasse, deren Parameter T ein Skalar ist. Ich möchte, wenn der skalare Punktdaten eines Datensatzes zu überprüfen, den gleichen Datentyp wie T.

Vorerst hat, was ich tue, ist eine Art Größenvergleich:

vtkDataArray *scalars = image->GetPointData()->GetScalars(); 
if(scalars->GetDataTypeSize() != sizeof(T)) 
{ 
    std::cerr<<"Incompatible types"<<std::endl; 
} 

Aber offensichtlich float und int sind beide der Größe 4, so dass es nicht wirklich funktioniert.

Irgendwelche Ideen?

+0

können Sie type_index verwenden, ich bereite ein Beispiel vor ... – norisknofun

Antwort

0

Nachdem ich Informationen von einigen Stellen gesammelt habe, kam ich zu dem Schluss, dass es keine Möglichkeit gibt, es einfach zu schreiben, ohne die Zuordnung zwischen den beiden Typenlisten selbst zu erstellen.

So, hier ist die eleganteste Art, wie ich das tun gefunden:

ich die Idee von norisknofun ‚s Karte verwendet, aber ich invertiert es. Ich habe nicht verwendet, weil es scheint, dass Sie den hash_code direkt aus dem Ergebnis typeid() erhalten können. Ich habe diese Zuordnung in eine Funktion, die Grundtyp zu VTK-Typ zu transformieren, weil es andere Zwecke als nur Vergleich dienen kann (siehe meine other post).

#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]; 
} 

daher einen VTK Datentyp zu vergleichen und einen Basistyp (mein Template-Parameter T), das tue ich:

vtkDataArray *scalars = image->GetPointData()->GetScalars(); 
if(scalars->GetDataType() != GetVTKType(typeid(T).hash_code())) 
{ 
    std::cerr<<"Incompatible types"<<std::endl; 
} 

Oder wenn ich eine nette Vergleichsfunktion soll als norisknofun tat es kann ich tun:

template < class T > 
bool is_same(long vtkType) 
{ 
    return vtkType != GetVTKType(typeid(T).hash_code()) 
} 

// somewhere.cpp 
if(!is_same<T>(scalars->GetDataType())) 
{ 
    std::cerr<<"Incompatible types"<<std::endl; 
} 
0

Ich denke, Sie müssen Ihr eigenes Mapping erarbeiten. Ihr Compiler muss C++ 11-konform sein mit RTTI aktiviert, aber jetzt unterstützen die meisten modernen Compiler diese Funktion.

Ich weiß nicht, was ist der C++ Äquivalent von 'Bit', 'id_type' und 'undurchsichtig' Typen ...

#include <iostream> 
#include <typeinfo> 
#include <typeindex> 
#include <cstdint> 
#include <string> 
#include <map> 

// copy from vtk header, use #include <vtkType.h> instead 
#define VTK_VOID   0 
#define VTK_BIT    1 
#define VTK_CHAR   2 
#define VTK_SIGNED_CHAR 15 
#define VTK_UNSIGNED_CHAR 3 
#define VTK_SHORT   4 
#define VTK_UNSIGNED_SHORT 5 
#define VTK_INT    6 
#define VTK_UNSIGNED_INT 7 
#define VTK_LONG   8 
#define VTK_UNSIGNED_LONG 9 
#define VTK_FLOAT   10 
#define VTK_DOUBLE   11 
#define VTK_ID_TYPE  12 
#define VTK_STRING   13 
#define VTK_OPAQUE   14 
#define VTK_LONG_LONG   16 
#define VTK_UNSIGNED_LONG_LONG 17 
#define VTK___INT64   18 
#define VTK_UNSIGNED___INT64 19 

// vtktypes 
    typedef long vtktypes ; 

    // standard c++ types 
    typedef std::size_t mytypes ; 
    typedef std::map< vtktypes, mytypes> map_t; 

template < class T > 
bool is_same(vtktypes x) 
{ 
    static std::map< vtktypes, mytypes> _map; 
    if(_map.empty()) 
    { 
     _map[VTK_VOID   ] = std::type_index(typeid(void)).hash_code(); 
     //_map[VTK_BIT    ] = std::type_index(typeid(void)).hash_code(); 
     _map[VTK_CHAR   ] = std::type_index(typeid(char)).hash_code(); 
     _map[VTK_SIGNED_CHAR ] = std::type_index(typeid(signed char)).hash_code(); 
     _map[VTK_UNSIGNED_CHAR ] = std::type_index(typeid(unsigned char)).hash_code(); 
     _map[VTK_SHORT   ] = std::type_index(typeid(short)).hash_code(); 
     _map[VTK_UNSIGNED_SHORT ] = std::type_index(typeid(unsigned short)).hash_code(); 
     _map[VTK_INT   ] = std::type_index(typeid(int)).hash_code(); 
     _map[VTK_UNSIGNED_INT ] = std::type_index(typeid(unsigned int)).hash_code(); 
     _map[VTK_LONG   ] = std::type_index(typeid(long)).hash_code(); 
     _map[VTK_UNSIGNED_LONG ] = std::type_index(typeid(unsigned long)).hash_code(); 
     _map[VTK_FLOAT   ] = std::type_index(typeid(float)).hash_code(); 

     _map[VTK_DOUBLE   ] = std::type_index(typeid(double)).hash_code(); 
     //_map[VTK_ID_TYPE   ] = type_index(typeid()).hash_code(); 
     _map[VTK_STRING   ] = std::type_index(typeid(std::string)).hash_code(); 
     //_map[VTK_OPAQUE   ] = type_index(typeid(void)).hash_code(); 
     _map[VTK_LONG_LONG   ]= std::type_index(typeid(long long)).hash_code(); 
     _map[VTK_UNSIGNED_LONG_LONG]= std::type_index(typeid(unsigned long long)).hash_code(); 
     _map[VTK___INT64   ]= std::type_index(typeid(int64_t)).hash_code(); 
     _map[VTK_UNSIGNED___INT64 ]= std::type_index(typeid(uint64_t)).hash_code(); 
    } 

    map_t::iterator it = _map.find(x); 
    return (it != _map.end()) && it->second == std::type_index(typeid(T)).hash_code(); 
} 

int main() 
{ 
    std::cout << "is same ? " << is_same<char>(2) << std::endl ; 
    std::cout << "is same ? " << is_same<std::string>(13) << std::endl ;  

    return 0; 
} 

In Ihrem Fall, können Sie es so verwenden:

vtkDataArray *scalars = image->GetPointData()->GetScalars(); 
if(!is_same<T>(scalars->GetDataTypeSize())) 
{ 
    std::cerr<<"Incompatible types"<<std::endl; 
} 
Verwandte Themen