July 12, 2016 Re: Simple overloading without complications | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adam Sansier | On Tuesday, 12 July 2016 at 16:30:05 UTC, Adam Sansier wrote:
> Doesn't matter, it's not what I asked.
Yeah, I'm not confident I understood your problem right. You can try to describe your problem better.
|
July 12, 2016 Re: Simple overloading without complications | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adam Sansier | 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),
);
....
}
|
July 12, 2016 Re: Simple overloading without complications | ||||
---|---|---|---|---|
| ||||
Posted in reply to Meta | 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;
Should be `import std.variant`.
|
July 12, 2016 Re: Simple overloading without complications | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kagamin | On Tuesday, 12 July 2016 at 17:17:31 UTC, Kagamin wrote:
> On Tuesday, 12 July 2016 at 16:30:05 UTC, Adam Sansier wrote:
>> Doesn't matter, it's not what I asked.
>
> Yeah, I'm not confident I understood your problem right. You can try to describe your problem better.
Criteria:
1. At most 2 one parameter functions be used, one that takes an int and the other a wstring.
2. They must be overloadable and allow for a literal string type to be passed for the wstring function. This prevents basic templates and variant techniques.
3. No duplication of code.
4. The wstring function only exists to find the index for the argument passed. It cannot do this without the int function being called first, as it initializes or gets data that cannot be done more than once. This forces some type of "break" in the flow of the int function.
suppose you have two functions and only two functions.
void Do(int i)
{
// stuff 1
// stuff 2 (uses i)
}
void Do(wstring s)
{
// stuff 1
// converts s to i, the same i that is used in Do(int)
// stuff 2 (uses i)
}
Obviously stuff 1 and stuff 2 are duplicates. stuff 1 does not not use i or s. stuff 2 does not use s.
The question is how to optimally, in terms of code duplication, reduce Do(string) so it does no extra work.
There are ways, obviously. But to satisfy the complete criteria is the hard part.
I could probably use some goto statements and asm to accomplish this, but probably quite a bit of work and tricky
void Do(wstring s)
{
// get i from s (a simple search), no big deal, a comment suffices
// create function call to (setup stack, modify first stack parameter, which is i, to use our new i
goto Doi;
}
void Do(int i)
{
// stuff 1
label Doi;
// stuff 2
}
The goto bypasses stuff1 in Do(int), and sets up i with the new value. This method would work but is a hack, not portable, etc. It is essentially the same idea as the yield I proposed, but less robust. A yield and continue construct would hide all the details and do something similar.
Again, this isn't about how to accomplish some goal, but how to accomplish it given the criteria/restraints proposed. It's a no brainier to do without the constraints.
|
July 12, 2016 Re: Simple overloading without complications | ||||
---|---|---|---|---|
| ||||
Posted in reply to Meta | 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. |
Copyright © 1999-2021 by the D Language Foundation