Thread overview | ||||||||
---|---|---|---|---|---|---|---|---|
|
November 02, 2009 Different class template args to generate same template instance? | ||||
---|---|---|---|---|
| ||||
I'd like to have a sub-class that's templated on a potentially-duplicated name and an optional disambiguating type. To illustrate: class Foo { } /* Three possible names/types are: - sam, human - zoe, human - zoe, starship */ class SubFoo(char[] name, char[] type) { static if(name == "sam" && type == "human") // create members specific to the only sam else static if(name == "zoe" && type == "human") // create members specific to the human zoe static if(name == "zoe" && type == "starship") // create members specific to the starship zoe else static assert(false, "Invalid name/type"); } But unlike in that example, *most* of the names will only exist as one possible type and will therefore be completely unambiguous just by themselves. So, I would really like to be able to make the type optional and just have a "static assert(false)" for any use of an ambiguous name that isn't disambiguated by a type. Kind of like this: class SubFoo(char[] name, char[] type="") { static if(name == "sam" && (type == "human" || type=="")) // create members specific to the only sam else static if(name == "zoe" && type == "human") // create members specific to the human zoe static if(name == "zoe" && type == "starship") // create members specific to the starship zoe static if(name == "zoe" && type == "") static assert(false, "zoe might be either the human or the starship, please specify which one"); else static assert(false, "Invalid name/type"); } Problem is, that won't work because SubFoo!("sam") and SubFoo!("sam", "human") are treated as different types. So...is there any trickery I could do so that SubFoo!("sam") and SubFoo!("sam", "human") would resolve to the same subclass of Foo? I don't think any solution involving merging the name/type fields into anything like "sam.human" would work because the valid names could be just about any sequence of chars (this source file will be generated by a tool) so any possible "disambiguated" string could potentially conflict with a plain non-disambiguated name. Names being any sequence of chars also rules out anything like "class SubFoo_sam_human : Foo", because name could be something like "++. /&". |
November 02, 2009 Re: Different class template args to generate same template instance? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nick Sabalausky | Hello Nick,
> So...is there any trickery I
> could do so that SubFoo!("sam") and SubFoo!("sam", "human") would
> resolve to the same subclass of Foo?
Make a SubFoo!(char[] s) that does your logic and if it passesa alises to SubFoo!(s,"")
|
November 02, 2009 Re: Different class template args to generate same template instance? | ||||
---|---|---|---|---|
| ||||
Posted in reply to BCS | "BCS" <none@anon.com> wrote in message news:a6268ffc3898cc29d1f554dfe2@news.digitalmars.com... > Hello Nick, > > >> So...is there any trickery I >> could do so that SubFoo!("sam") and SubFoo!("sam", "human") would >> resolve to the same subclass of Foo? > > Make a SubFoo!(char[] s) that does your logic and if it passesa alises to SubFoo!(s,"") > > I'm not sure I understand...? |
November 02, 2009 Re: Different class template args to generate same template instance? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nick Sabalausky | Nick Sabalausky wrote:
> "BCS" <none@anon.com> wrote in message news:a6268ffc3898cc29d1f554dfe2@news.digitalmars.com...
>> Hello Nick,
>>
>>
>>> So...is there any trickery I
>>> could do so that SubFoo!("sam") and SubFoo!("sam", "human") would
>>> resolve to the same subclass of Foo?
>> Make a SubFoo!(char[] s) that does your logic and if it passesa alises to SubFoo!(s,"")
>>
>>
>
> I'm not sure I understand...?
>
>
I think what he's trying to say is
template SubFoo!(char[] name, char[] type) {
static if (name == "sam" && (type == "human" || type == "")) alias _SubFoo!("sam", "human") SubFoo;
/* etc */
}
|
November 02, 2009 Re: Different class template args to generate same template instance? | ||||
---|---|---|---|---|
| ||||
Posted in reply to downs | "downs" <default_357-line@yahoo.de> wrote in message news:hcnjit$4na$1@digitalmars.com... > Nick Sabalausky wrote: >> "BCS" <none@anon.com> wrote in message news:a6268ffc3898cc29d1f554dfe2@news.digitalmars.com... >>> Hello Nick, >>> >>> >>>> So...is there any trickery I >>>> could do so that SubFoo!("sam") and SubFoo!("sam", "human") would >>>> resolve to the same subclass of Foo? >>> Make a SubFoo!(char[] s) that does your logic and if it passesa alises >>> to >>> SubFoo!(s,"") >>> >>> >> >> I'm not sure I understand...? >> >> > > I think what he's trying to say is > > template SubFoo!(char[] name, char[] type) { > static if (name == "sam" && (type == "human" || type == "")) alias > _SubFoo!("sam", "human") SubFoo; > /* etc */ > } Ahh! Thanks all, that works perfectly: ------------------------------------------------------------- module foo; class Foo { protected char[] _n="Plain Foo"; char[] n() { return _n.dup; } } template SubFoo(char[] name, char[] type="") { static if (name == "sam" && (type == "human" || type == "")) alias _SubFoo!(name, "human") SubFoo; else static if( (name == "zoe" && type == "human") || (name == "zoe" && type == "starship") ) alias _SubFoo!(name, type) SubFoo; else static if(name == "zoe" && type == "") static assert(false, "Name '"~name~"' is ambiguous"); else static assert(false, "Invalid name/type: '"~name~"' '"~type~"'"); } private class _SubFoo(char[] name, char[] type) : Foo { static if(name == "sam" && type == "human") this() { _n = "sam human"; } else static if(name == "zoe" && type == "human") this() { _n = "zoe human"; } else static if(name == "zoe" && type == "starship") this() { _n = "zoe starship"; } else static assert(false, "Invalid name/type: '"~name~"' '"~type~"'"); } ------------------------------------------------------------- module main; import tango.io.Stdout; import foo; void main() { auto f = new Foo(); auto s_ = new SubFoo!("sam"); auto sh = new SubFoo!("sam", "human"); auto zh = new SubFoo!("zoe", "human"); auto zs = new SubFoo!("zoe", "starship"); // ERROR: Name 'zoe' is ambiguous //auto z_ = new SubFoo!("zoe"); // ERROR: Invalid name/type 'dummy' 'dude' //auto d_ = new SubFoo!("dummy", "dude"); Stdout.formatln("f : {}", f.n); // OUT: f : Plain Foo Stdout.formatln("s_: {}", s_.n); // OUT: s_: sam human Stdout.formatln("sh: {}", sh.n); // OUT: sh: sam human Stdout.formatln("zh: {}", zh.n); // OUT: zh: zoe human Stdout.formatln("zs: {}", zs.n); // OUT: zs: zoe starship } ------------------------------------------------------------- |
November 02, 2009 Re: Different class template args to generate same template instance? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nick Sabalausky | "Nick Sabalausky" <a@a.a> wrote in message news:hcnlh7$msb$1@digitalmars.com... > "downs" <default_357-line@yahoo.de> wrote in message news:hcnjit$4na$1@digitalmars.com... >> Nick Sabalausky wrote: >>> "BCS" <none@anon.com> wrote in message news:a6268ffc3898cc29d1f554dfe2@news.digitalmars.com... >>>> Hello Nick, >>>> >>>> >>>>> So...is there any trickery I >>>>> could do so that SubFoo!("sam") and SubFoo!("sam", "human") would >>>>> resolve to the same subclass of Foo? >>>> Make a SubFoo!(char[] s) that does your logic and if it passesa alises >>>> to >>>> SubFoo!(s,"") >>>> >>>> >>> >>> I'm not sure I understand...? >>> >>> >> >> I think what he's trying to say is >> >> template SubFoo!(char[] name, char[] type) { >> static if (name == "sam" && (type == "human" || type == "")) alias >> _SubFoo!("sam", "human") SubFoo; >> /* etc */ >> } > > Ahh! Thanks all, that works perfectly: > > ------------------------------------------------------------- > module foo; > > class Foo > { > protected char[] _n="Plain Foo"; > char[] n() > { > return _n.dup; > } > } > > template SubFoo(char[] name, char[] type="") > { > static if (name == "sam" && (type == "human" || type == "")) > alias _SubFoo!(name, "human") SubFoo; > else static if( > (name == "zoe" && type == "human") || > (name == "zoe" && type == "starship") > ) > alias _SubFoo!(name, type) SubFoo; > else static if(name == "zoe" && type == "") > static assert(false, "Name '"~name~"' is ambiguous"); > else > static assert(false, "Invalid name/type: '"~name~"' '"~type~"'"); > } > > private class _SubFoo(char[] name, char[] type) : Foo > { > static if(name == "sam" && type == "human") > this() { _n = "sam human"; } > else static if(name == "zoe" && type == "human") > this() { _n = "zoe human"; } > else static if(name == "zoe" && type == "starship") > this() { _n = "zoe starship"; } > else > static assert(false, "Invalid name/type: '"~name~"' '"~type~"'"); > } > ------------------------------------------------------------- > module main; > import tango.io.Stdout; > import foo; > > void main() > { > auto f = new Foo(); > auto s_ = new SubFoo!("sam"); > auto sh = new SubFoo!("sam", "human"); > auto zh = new SubFoo!("zoe", "human"); > auto zs = new SubFoo!("zoe", "starship"); > > // ERROR: Name 'zoe' is ambiguous > //auto z_ = new SubFoo!("zoe"); > > // ERROR: Invalid name/type 'dummy' 'dude' > //auto d_ = new SubFoo!("dummy", "dude"); > > Stdout.formatln("f : {}", f.n); // OUT: f : Plain Foo > Stdout.formatln("s_: {}", s_.n); // OUT: s_: sam human > Stdout.formatln("sh: {}", sh.n); // OUT: sh: sam human > Stdout.formatln("zh: {}", zh.n); // OUT: zh: zoe human > Stdout.formatln("zs: {}", zs.n); // OUT: zs: zoe starship > } > ------------------------------------------------------------- > Oops, just realized that main doesn't necessarily prove that the SubFoo!("sam") and SubFoo!("sam", "human") are the same types. But this passes fine, so all looks ok, thanks again! : static assert(is( SubFoo!("sam") == SubFoo!("sam", "human") )); |
Copyright © 1999-2021 by the D Language Foundation