I'm trying to find an efficient way to invoke a specific C++ template type based dynamic value of a variable. Currently I'm not clear on how to approach this, except by using large and ugly if/else selector for a large set of permutations as in the example below. As you can see this is not pretty.
Instead I'd like to invoke suitable template dynamically without huge if/else selector...
Any advise from the C++ template masters out there would be much appreciated.
// crude generic data converter template invoked based on dynamic in/out buffer type
template <class dstType, class srcType>
void ConvertCopy(unsigned char* dst, const unsigned char* src, int size)
{
// requires same in/out buffer same dimensions
if (typeid(srcType) != typeid(dstType))
{
dstType* c_dst = (dstType*)dst;
srcType* c_src = (srcType*)src;
for(int i=0;i<size;i++)
c_dst[i] = (dstType)c_src[i];
}
else
memcpy(dst, src, size * sizeof(srcType)); // Plain copy
}
void test()
{
const int buffersize = 100;
int inbuffer[buffersize];
double outbuffer[buffersize];
unsigned char* anyIn = (unsigned char*)inbuffer;
unsigned char* anyOut = (unsigned char*)outbuffer;
int my_in_type = 1;
int my_out_type = 3;
if(my_in_type == 1) { // int
if(my_out_type == 1) ConvertCopy<int, int>(anyOut, anyIn, buffersize); // int -> int
if(my_out_type == 2) ConvertCopy<float, int>(anyOut, anyIn, buffersize); // int -> float
if(my_out_type == 3) ConvertCopy<double, int>(anyOut, anyIn, buffersize); // int -> double
// ...
}
else if(my_in_type == 2) { // unsigned int
if(my_out_type == 1) ConvertCopy<int, unsigned int>(anyOut, anyIn, buffersize); // unsigned int -> int
if(my_out_type == 2) ConvertCopy<float, unsigned int>(anyOut, anyIn, buffersize); // unsignedint -> float
if(my_out_type == 3) ConvertCopy<double, unsigned int>(anyOut, anyIn, buffersize); // unsigned int -> double
// ...
}
else {}
// ...
}
if/elsebranch based on whether the types are the same or not?std::anyint size? How meaningful are sizes like -1, -7, -10, -12, ...???memcpycan fail badly if applied on complex types likestd::string. Better usestd::copyinstead, if templates are involved.convertCopy(DstType* dst, SrcType const* src). If you cannot, a lookup table might be an option:void (*pointers[])(unsigned char*, unsigned char const*, size_t) = { convertCopy<int, int>, convertCopy<int, double>, ... };. Then you could calculate the appropriate index withoutType * NumberOfTypes + inType.