Simple overloading without complications

Adam Sansier via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Mon Jul 11 21:23:07 PDT 2016


I have a function that does some weird stuff, and can't really 
change it to make life easier(due to how windows work, COM, 
etc..).

The function normally takes a string, a name, and does its 
think(which is the complex part that I can't change).

But I also want to overload it so the function takes an int. I 
can't simply overload the function and call the string version or 
vice versa as one would normally do because this would require 
initializing twice, which can't happen because the way the code 
works.

The int value is a lookup into an array, and the name version 
searches the array for a name match. I can't overload the int 
version and search the name first because the data doesn't exist 
yet

void Do(string name)
{
     // get index of name in array
     // can't find x corresponding to name because data is not 
initialized.
     // Can't init data more than once. Can't add init flag(could 
but want to find a better solution)
     Do(x);
}

void Do(int index)
{
     Init_Data();
     ...
}



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
     }

     ....
}



What I really want is a sort of mix between the first overloaded 
method and the second case.


The string version is really just finding the index of the string 
and should insert itself inside the int version similar to the 
static if.

I know there are many ways and many are going to fuss over doing 
it with a bool or duplicate the function or whatever. I'm looking 
for an elegant solution for what I want, I know there are other 
ways... not interested in them. Given that D has so many meta 
capabilities, I'm hoping there is some elegant solution.

To make it clear.

void Do(int index)
{
    // Does stuff

     // If index was a string instead of a name, we would do a 
lookup to find the index for name. Everything else is exactly the 
same

    // does stuff with index
}

void Do(string name)
{
     // somehow
     Do(name_index);
}


Another way is to use a lambda:

void Do(int index, int delegate(data) toName)
{
     // Does stuff
     if (toName) index = toName(data);
     // Do stuff with index
}

void Do(string name)
{
     Do(0, (data) { find i for name; return i; });
     // which plugs in the lambda
}



The problem with all these ways is that they complicate matters 
and either duplicate a lot of code or create hard to maintain 
code or problems in other areas. e.g., if I use the template 
method any literal string is not automatically converted do("this 
won't be treated as a wstring").

If a bool is used, I have to have the initialization code in both 
functions. Doesn't seam like much until you scale the problem up.

What would be nice is something akin to yield:

void Do(int index)
{
     // Does stuff
     ?yield // If Do is called in a special way, we break out of 
the code here
     // Do stuff with index
}

void Do(string name)
{

     yield Do(0);
     find i for name;
     continue Do(i);
}


This keeps everything internal and from the outside everything 
looks as it should, avoids duplicate code, extra arguments, 
flags, etc.

Is it possible?








More information about the Digitalmars-d-learn mailing list