www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - struct and class member alias

reply Stuart Murray <stuart.w.murray fakey.nospambots.gmail.com> writes:
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);
	}
}
Jun 05 2007
parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"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 :(
Jun 05 2007
parent reply Stuart Murray <stuart.w.murray fakey.nospambots.gmail.com> writes:
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 :)
Jun 05 2007
parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"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.
Jun 06 2007
parent reply Stuart Murray <stuart.w.murray fakey.nospambots.gmail.com> writes:
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.
Jun 06 2007
parent "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"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*
Jun 06 2007