Thread overview
struct and class member alias
Jun 05, 2007
Stuart Murray
Jun 06, 2007
Stuart Murray
Jun 06, 2007
Stuart Murray
June 05, 2007
In the following, the aliases have no apparent effect (although they do compile). Is there a way to achieve a similar effect? I just want to be able to access
boxInstance.pos.x
using
boxInstance.x

I got the alias idea from the function page in the documentation:
http://digitalmars.com/d/function.html
under Function Inheritance and Overloading
obviously it doesn't describe the same thing, but I figured I'd give it a shot.
Given that it doesn't seem to work I was thinking that it might be a handy feature to have in the language?

I tried this as a struct(suitably modified) also.

public class Coord
{
	int x, y;

	this
	   (in int x, in int y)
	{
		this.x = x;
		this.y = y;
	}
}

public class Box
{
	Coord pos, size;

	alias pos.x  x;
	alias pos.y  y;
	alias size.x w;
	alias size.y h;

	this
	   (in int x, in int y,
		in int w, in int h)
	{
		pos  = new Coord(x, y);
		size = new Coord(w, h);
	}
}
June 05, 2007
"Stuart Murray" <stuart.w.murray@fakey.nospambots.gmail.com> wrote in message news:f4430d$14oc$1@digitalmars.com...
> In the following, the aliases have no apparent effect (although they do
> compile). Is there a way to achieve a similar effect? I just want to be
> able to access
> boxInstance.pos.x
> using
> boxInstance.x

It doesn't compile; I get

foo.d(19): Error: pos.x is used as a type
foo.d(20): Error: pos.y is used as a type
foo.d(21): Error: size.x is used as a type
foo.d(22): Error: size.y is used as a type

It's no surprise, either.  You're not allowed to make aliases of expressions.

What you can do is make "properties."  You have a setter and a getter for each property.  Because of some syntactic sugar, you can write "a.x" to mean "a.x()" and "a.x = 5" to mean "a.x(5)".

Here's the Box class with read/write properties for x and y defined.

public class Box
{
    Coord pos, size;

    this(in int x, in int y, in int w, in int h)
    {
        pos  = new Coord(x, y);
        size = new Coord(w, h);
    }

    public int x()
    {
        return pos.x;
    }

    public void x(int val)
    {
        pos.x = val;
    }

    public int y()
    {
        return pos.y;
    }

    public void y(int val)
    {
        pos.y = val;
    }
}

It's a little more verbose than you might like.

Another solution would be to make public reference fields in Box that refer to the inner pos.x, pos.y etc. members.  But D doesn't have generic reference types, so foo :(


June 06, 2007
Jarrett Billingsley Wrote:

> 
> "Stuart Murray" <stuart.w.murray@fakey.nospambots.gmail.com> wrote in message news:f4430d$14oc$1@digitalmars.com...
> > In the following, the aliases have no apparent effect (although they do
> > compile). Is there a way to achieve a similar effect? I just want to be
> > able to access
> > boxInstance.pos.x
> > using
> > boxInstance.x
> 
> It doesn't compile; I get
> 
> foo.d(19): Error: pos.x is used as a type
> foo.d(20): Error: pos.y is used as a type
> foo.d(21): Error: size.x is used as a type
> foo.d(22): Error: size.y is used as a type
> 
> It's no surprise, either.  You're not allowed to make aliases of expressions.
> 
> What you can do is make "properties."  You have a setter and a getter for each property.  Because of some syntactic sugar, you can write "a.x" to mean "a.x()" and "a.x = 5" to mean "a.x(5)".
> 
> Here's the Box class with read/write properties for x and y defined.
> 
> public class Box
> {
>     Coord pos, size;
> 
>     this(in int x, in int y, in int w, in int h)
>     {
>         pos  = new Coord(x, y);
>         size = new Coord(w, h);
>     }
> 
>     public int x()
>     {
>         return pos.x;
>     }
> 
>     public void x(int val)
>     {
>         pos.x = val;
>     }
> 
>     public int y()
>     {
>         return pos.y;
>     }
> 
>     public void y(int val)
>     {
>         pos.y = val;
>     }
> }
> 
> It's a little more verbose than you might like.
> 
> Another solution would be to make public reference fields in Box that refer to the inner pos.x, pos.y etc. members.  But D doesn't have generic reference types, so foo :(
> 
> 

Interesting that it doesn't compile for you.. It definitely does for me (using DMD v1.014) This is the example I referred to, if anyones interested:

class A
{
    int foo(int x) { ... }
    int foo(long y) { ... }
}

class B : A
{
    alias A.foo foo;
    override int foo(long x) { ... }
}

Its in the documentation. As I said, it's slightly different thing, but it seems to .. *match*..

It is unfortunate to not have reference types a la C++, but I love D in almost every other way :)
June 06, 2007
"Stuart Murray" <stuart.w.murray@fakey.nospambots.gmail.com> wrote in message news:f458q0$2vea$1@digitalmars.com...
>
> Interesting that it doesn't compile for you.. It definitely does for me
> (using DMD v1.014)
> This is the example I referred to, if anyones interested:
>
> class A
> {
>    int foo(int x) { ... }
>    int foo(long y) { ... }
> }
>
> class B : A
> {
>    alias A.foo foo;
>    override int foo(long x) { ... }
> }
>
> Its in the documentation. As I said, it's slightly different thing, but it seems to .. *match*..

Oh, well _that_ will compile :)  It's because "A.foo" is not an expression, it's a symbol.  You're saying "bring my superclass's implementation of foo into this namespace so it can be overloaded."  A.foo is a name, so you can alias it.  The "A." is just there as a marker to say where foo lives.

In your example, pos and size are class instances; they have no meaning until they've been new'ed.  Furthermore, pos.x is not a symbol, it's an expression -- it's an access to a member whose location can't be determined at compile time.  So, you can't alias it.


June 06, 2007
Jarrett Billingsley Wrote:

> "Stuart Murray" <stuart.w.murray@fakey.nospambots.gmail.com> wrote in message news:f458q0$2vea$1@digitalmars.com...
> >
> > Interesting that it doesn't compile for you.. It definitely does for me
> > (using DMD v1.014)
> > This is the example I referred to, if anyones interested:
> >
> > class A
> > {
> >    int foo(int x) { ... }
> >    int foo(long y) { ... }
> > }
> >
> > class B : A
> > {
> >    alias A.foo foo;
> >    override int foo(long x) { ... }
> > }
> >
> > Its in the documentation. As I said, it's slightly different thing, but it seems to .. *match*..
> 
> Oh, well _that_ will compile :)  It's because "A.foo" is not an expression, it's a symbol.  You're saying "bring my superclass's implementation of foo into this namespace so it can be overloaded."  A.foo is a name, so you can alias it.  The "A." is just there as a marker to say where foo lives.
> 
> In your example, pos and size are class instances; they have no meaning until they've been new'ed.  Furthermore, pos.x is not a symbol, it's an expression -- it's an access to a member whose location can't be determined at compile time.  So, you can't alias it.
> 
> 

Thanks, that all seems to make sense. Thanks a lot for your help. As a last note I would suggest that the example:

> > class A
> > {
> >    int foo(int x) { ... }
> >    int foo(long y) { ... }
> > }
> >
> > class B : A
> > {
> >    alias A.foo foo;
> >    override int foo(long x) { ... }
> > }

seems a bit of a hacky way to fix the overload choosing thing, I suspect most newcomers would assume that subclass member functions would overload with superclass members of the same name. But such is life.

June 06, 2007
"Stuart Murray" <stuart.w.murray@fakey.nospambots.gmail.com> wrote in message news:f46eg2$1qce$1@digitalmars.com...
> Thanks, that all seems to make sense. Thanks a lot for your help. As a last note I would suggest that the example:
>
>> > class A
>> > {
>> >    int foo(int x) { ... }
>> >    int foo(long y) { ... }
>> > }
>> >
>> > class B : A
>> > {
>> >    alias A.foo foo;
>> >    override int foo(long x) { ... }
>> > }
>
> seems a bit of a hacky way to fix the overload choosing thing, I suspect most newcomers would assume that subclass member functions would overload with superclass members of the same name. But such is life.

_Everyone_ does.  But "this is the way C++ does it," as if that means anything.  *sigh*