On Tuesday, 12 July 2016 at 18:52:08 UTC, Meta wrote:
On Tuesday, 12 July 2016 at 04:23:07 UTC, Adam Sansier wrote:
Now, I could simply make Do a template method but then this prevents it being a virtual function.

void Do(T)(T name) if (is(T == string) || is(T == int))
{
    Init_Data();

    static if (is(T == string))
    {
        ...Get index from name
    }

    ....
}

You could always use std.variant.algebraic which implements runtime polymorphism:

import std.algebraic;

alias intOrString = Algebraic!(int, string);

void Do(intOrString indexOrName)
{
    Init_Data();

    int index = indexOrName.visit!(
        (int i) => i,
        (string s) => getIndexByName(s),
    );

    ....
}

I thought about this, but kinda hacky. Because I'm using wstring I would basically have to do:

alias intOrString = Algebraic!(int, string, wstring);

void Do(intOrString indexOrName)
{
    Init_Data();

    int index = indexOrName.visit!(
        (int i) => i,
        (string s) => getIndexByName(to!wstring(s)),
        (wstring s) => getIndexByName(s),
    );

    ....
}

It's not terrible, but not better than using templates, which would be more performant.

void Do(T arg) if (is(arg == string) || is(arg == int) || is(arg == wstring)
{
   int i = 0;
   Init_Data();
   static if (is(arg == string) || is(arg == wstring))
   {
       wstring s;
       static if (is(arg == string))
           s = to!wstring(arg);
       else
           s = arg;
       // Find i for string
       i = Findi(arg);
   } else
       i = arg;
   ....
}


It's not very elegant either but basically works and solves the problem... and also does it in one function. It's probably as close as one can get in D to what I want, I'm hoping someone find a better way.






Reply via email to