Instantiating templates where type is known only at run time

Craig Dillabaugh cdillaba at cg.scs.carleton.ca
Tue Nov 19 03:47:39 PST 2013


this question came up in some C++ work I am doing, but since the
solutions are likely nicer in D, I wanted to ask how it could be
solved in D.

First for some motivation.  I am doing image processing work
where the images are simply an array of data, where the data type
can be any numeric type. The data is stored as binary files and
assume I have some way of figuring out the data type for an image.

Say I want to implement the function along the following lines,
and imagine I have a sane reason for wanting to do such a thing:

//  Assume images are of the same dimensions. Result is
//  saved in Out.
void add(T,U,V)(Image!T A, Image!U B, Image!V Out) {
      ...
}

Now assume I have three variables ImgAType, ImgBType, and
ImgCType (I refer to these variables without specifying their
type, but hopefully it is clear what is going on) then to
implement add() I end up with a lengthy if..else statement or
nasty nested switch ... case statements to handle all the
possible combinations of ubyte, short, uint, float, double for
each of the three image types.  I will use an if() version
example:

if( ImgAType == SHT && ImgBType == UINT && ImgCType == DBL ) {
      Image!short A = new Image!short( filename_of_A );
      Image!uint  B = new Image!uint( filename_of_B );
      Image!double Out = new Image!double( filename_of_Out );
      add(A,B,Out);
} else { //next case and so on .... }

Since the types can be any numeric type there are a lot of
'combinations' of images. I won't add a float and double together
and generate a ubyte image, but there are still many valid
combinations.  However, any way you slice it you end up with a
very long, repetitive bunch of code.

A co-worker of mine came up with (or found) the following
solution. I thought is was clever. It cuts down on repetitive
code, but man is it ugly:

void add( ImgAType, ImgBType, ImgCType, //File names  ) {
     if( ImgAType == UBYTE) AddStep1!ubyte(ImgBType, ImgCType,
//Files );
     else if( ImgAType == SHT) AddStep1!short(ImgBType, ImgCType,
//Files );
     //and so on
}

void AddStep1(T)(ImgBType, ImgCType, //File names ) {
     if( ImgBType == UBYTE) AddStep2!(T,ubyte)(ImgCType, //Files );
     else if( ImgBType == SHT) AddStep2!(T,short)(ImgCType, //Files
);
     //and so on.
}

void AddStep2(T,U)(ImgCType, //File names ) {
     if( ImgCType == UBYTE) AddStep3!(T,U,ubyte)( //Files );
     else if(ImgCType == SHT) AddStep3!(T,U,short)( //Files );
     //and so on
}

void AddStep3(T,U,V)( //File names ) {
     //Do the actual work!
}

Anyway, I hope that is clear what we are trying to do.  So my
question is, is there a nice way in D to instantiate all the
necessary templated functions, and call the correct version at
run time, without resorting one of the methods above.

Anyway, thanks to whoever takes the time to read all that, let
alone come up with an answer.


More information about the Digitalmars-d-learn mailing list