Let's say I have a class template whose type parameter will be drawn from a 
small, fixed-ahead-of-time set of types, but which type won't be known until 
runtime.  For example, say I would like to operate on a vector of 
floating-point values read in from disk, but I won't know if it will be a 
vector of floats or doubles until I read it in.  Is there a way to write one 
codepath that handles both types, or do I need to switch on the (dynamic) type 
and repeat the same code only with differing template instantiations?

Here is some code that illustrates the basic idea, with both the 
switch-at-runtime implementation and my "dream in code" implementation that 
doesn't compile:

----------------------------------
import std.stdio;
import std.math;
import std.c.stdlib;

class Container (T)
{
    this(T c)
    {
        this.c = c;
    }
    
    public:
    T c;
}

void dostuff (T) (T cont)
{
    writefln("%.12f", cont.c);
}

int main(string[] args)
{
    string precision = "double";
    if (args.length > 1 && args[1] == "single")
        precision = "single";

    // This works, but seems cumbersome
    switch (precision)
    {
        case "single":
            auto cont = new Container!(float)(PI);
            dostuff(cont);
            break;
        case "double":
            auto cont = new Container!(double)(PI);
            dostuff(cont);
            break;
        default:
            writefln("Error: unknown type '%s'.", precision);
            exit(1);
    }

    // Something like this would be nice
    auto cont = newContainer(precision);    
    dostuff(cont);
    
    return 0;
}


// Trying to return a "generic" Container, that can take on several types
// This gives error "class classtest.Container(T) is used as a type"
Container newContainer (string precision)
{
    switch (precision)
    {
        case "single":
            return new Container!(float)(PI);
        case "double":
            return new Container!(double)(PI);
        default:
            writefln("Error: unknown type '%s'.", precision);
            exit(1);
    }
}
----------------------------------------

It would be nice if the compiler could recognize "this is a function that can 
return different types; I will generate code for each possibility and pick the 
correct one at runtime."  But D doesn't support overloading functions on return 
type.  So: is there a way to do this nicely, or do I bite the bullet and switch?

Reply via email to