"inout return type" and "inout variable"

Regan Heath regan at netwin.co.nz
Thu Mar 16 14:51:37 PST 2006


On Thu, 16 Mar 2006 06:34:34 +0000 (UTC), Hong Wing  
<Hong_member at pathlink.com> wrote:
> Thanks everyone here for your great work in D, especially Walter who  
> makes it
> all happen.
> Here I am requesting a feature, which is "inout variable" and "inout  
> return
> type"
> Rationale, for the example below,
>
> struct Foo
> {
> int x, int y, int z;
> }
>
> class Bar
> {
> private:
> Foo m_foo;
> public:
> Foo foo() { return m_foo; }
> Foo foo(Foo value) { return m_foo = value; }
> }
>
> now if i want to change the value of m_foo.x to 5, i have to do
>
> Foo foo = bar.foo;
> foo.x   = 5;
> bar.foo = foo;
>
> it would be nice if I can define a return type as "inout Foo"
> inout Foo foo() { return m_foo;}
>
> To extend it further, one might want to define inout variables as
> inout Foo foo = bar.foo;
>
> Advantages:
>
> 1. efficiency, one can directly change the states of the struct instead  
> of
> making a copy first, change the copy, and put the result back to the  
> struct
>
> 2. less buggy, having to type 3 lines always increases chance of bugs,  
> also,
> someone might inadvertantly do bar.foo.x = 5 and forgot that he is  
> working on a
> copy
>
> 3. reduce the use of pointers, the above can be achieved using pointers,  
> but it
> means defining two versions of the same method every time a struct  
> property is
> written.

You're essentially asking for the ability to have variables which are  
references to structs (at least during assignment) and to return  
references to structs, all without using the pointer syntax. I think these  
things are un-necessary, and I think what you want can be achieved with  
pointers, without the penalty you mention in #3 above, see:

import std.string;
import std.stdio;

struct Foo
{
	int x;
	int y;
	int z;
	char[] toString() { return  
"("~std.string.toString(x)~","~std.string.toString(y)~","~std.string.toString(z)~")";  
}
}

class Bar
{
private:
	Foo m_foo;
public:
	Foo* foo() { return &m_foo; }
	Foo* foo(Foo* value) { m_foo = *value; return foo(); }	
	Foo* foo(Foo value)  { m_foo = value;  return foo(); }
}

void main()
{
	Bar b = new Bar();
	Bar c = new Bar();
	Foo t;
	
	b.foo.x = 1;
	b.foo.y = 2;
	b.foo.z = 3;	
	writefln(b.foo.toString());
	
	c.foo = b.foo;
	writefln(c.foo.toString());
	
	t.x = 4;
	t.y = 5;
	t.z = 6;
	writefln(t.toString());
	
	b.foo = t;
	writefln(b.foo.toString());
}

Note: The explicit "toString" calls are required because otherwise it  
prints the pointer address.

Regan



More information about the Digitalmars-d mailing list