Class templates with types determined at runtime

Doctor J nobody at nowhere.com
Tue Apr 7 20:37:59 PDT 2009


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?


More information about the Digitalmars-d-learn mailing list