问题
I have a template class myClass<T>
, where T can be a scalar (float, int, double, etc.)
I would like to create a vtkFloatArray
, vtkIntArray
, or vtkDoubleArray
, depending on the type T.
I thought that vtkDataArrayTemplate<T>
would be a good solution.
Unfortunately, it is a virtual class, so I can't write this :
vtkSmartPointer< vtkDataArrayTemplate<T> > array = vtkSmartPointer<vtkDataArrayTemplate<T> >::New();
because when I try to instantiate a myClass, I get the error :
error: invalid conversion from ‘vtkObject*’ to ‘vtkDataArrayTemplate<float>*’ [-fpermissive]`
I think it's because vtkDataArrayTemplate::New()
doesn't exist (because the class is virtual), so vtkObject::New()
is called instead. Then we understand that it can't transform a vtkObject
into a vtkDataArrayTemplate
.
So my question is:
Is there an non-virtual version of vtkDataArrayTemplate
that would allow me to create a vtkFloatArray
when T is float
, vtkDoubleArray
when T is double
, etc. ?
P.S: I use VTK 6.0.0
回答1:
Following the same logic of the other vtk question, you can make a factory with the a map of type
std::map< vtktypes , std::function< void*() > > _map;
std::function< void*() >
aims to be a simple object creator, returning void*
which then needs to be statically casted into the target type.
like :
_map[VTK_INT] = [](){ return new vtkFloatArray(); }
回答2:
An email to the vtk-users mailing list helped me on this too. A useful static function in vtkDataArray has been pointed to me:
vtkDataArray::CreateDataArray(int dataType)
It allows to create a data array of the type dataType.
Now, to transform the template parameter T
into a vtk type, I used the code I mentionned in this other post: (thank you 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 the final code is:
vtkDataArray *array =
vtkDataArray::CreateDataArray(GetVTKType(typeid(T).hash_code()));
来源:https://stackoverflow.com/questions/36475138/non-virtual-version-of-vtkdataarraytemplate