| Thread overview | ||||||
|---|---|---|---|---|---|---|
|
June 09, 2016 strettosis@tutanota.com | ||||
|---|---|---|---|---|
| ||||
I have some class like
class bar { }
class foo : bar
{
bar[] stuff;
}
and have another class
class dong : bar
{
int x;
}
Now sometimes stuff will contain dong's, but I cannot access its members it without a cast.
fooo.stuff[0].x // invalid because bar doesn't contain x;
Hence,
((cast(dong)foo.stuff[0]).x is the normal way with a possible type check.
But in my case I will never mix different types in stuff and will always use it properly or do type checking in the cases I might mix.
Rather than add a dong[] dongs; to foo, which increases the size of foo and wastes memory just to prevent the cast, I'm curious if there is any other way to solve this problem?
I simply want to do foo.stuff[0].x and have foo.stuff[0] be treated as an image.
Is an opDispatch and/or opIndex required or is there some alias trick that can be used?
I'd rather access like foo.dongs[0].x without defining a dong array directly in foo, but simply alias to stuff with an implicit cast to dong.
| ||||
June 09, 2016 Re: strettosis@tutanota.com | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Stretto | Ultimately what I want to do is access a member
foo.Dongs[i];
Where Dongs is essentially a "view" in to the Bars array and only accesses types of type Dong.
It seems one can't do both an override on a name("Dongs") and an index on the overridden name(`[i]`)?
It is not appropriate to use foo.Dongs(i).
A clear example:
https://dpaste.dzfl.pl/7ea52a0f21ce
| |||
June 10, 2016 Re: strettosis@tutanota.com | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Stretto | On Thursday, 9 June 2016 at 22:19:33 UTC, Stretto wrote:
> I have some class like
>
> class bar { }
> class foo : bar
> {
> bar[] stuff;
> }
>
> and have another class
>
> class dong : bar
> {
> int x;
> }
>
>
> Now sometimes stuff will contain dong's, but I cannot access its members it without a cast.
>
> fooo.stuff[0].x // invalid because bar doesn't contain x;
>
> Hence,
>
> ((cast(dong)foo.stuff[0]).x is the normal way with a possible type check.
>
> But in my case I will never mix different types in stuff and will always use it properly or do type checking in the cases I might mix.
>
That's just the nature of working with class hierarchies. A Derived is always a Base, but a Base might not be a Derived. If your Bar array in Foo will always hold only one type of Bar, then you can parameterize Foo with a type:
###########################
class Bar { }
// Only accept types that are implicitly convertible to Bar
class Foo(T : Bar) : Bar
{
T[] stuff;
}
class Dong : Bar
{
int x;
this(int x) { this.x = x; }
}
void main()
{
import std.stdio;
auto foo = new Foo!Dong();
foo.stuff ~= new Dong(10);
writeln(foo.stuff[0].x);
}
###########################
Another option is to use a parameterized getter, which is somewhat cleaner than a cast.
###########################
class Foo : Bar
{
Bar[] stuff;
T get(T : Bar)(size_t index)
{
return cast(T)stuff[index];
}
}
void main()
{
import std.stdio;
auto foo = new Foo();
foo.stuff ~= new Dong(10);
writeln(foo.get!Dong(0).x);
}
###########################
| |||
June 11, 2016 Re: strettosis@tutanota.com | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Mike Parker | you could also use a simple wrapped cast
Ret castTo(Ret, T)(T t) if(is(T == class))
{
return cast(Ret) t;
}
then do
foo.stuff[0].castTo!Dong.x.writeln;
and if you want to guard the access you could try
foo.stuff[0].castTo!Dong.cc!((d){d.x = 5;});
cc is an alias for checkCall which is a template you can find here
http://forum.dlang.org/thread/ltalqpmpscdoziserqqx@forum.dlang.org,
it treats Type.init as false and ignores the call to fun.
but its not restricted to nullables only e.g.
float someF;
iota(0, someF).writeln; // normally would throw an AssertError
someF.cc!(f => iota(0, f)).writeln; // returns an empty range without calling iota, as float.nan is treated as false.
same as
0.0.cc!(f => iota(0, f)).writeln;
| |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply