Thread overview | ||||||||
---|---|---|---|---|---|---|---|---|
|
July 04, 2004 another bug that 'in' enforcing 'const' would have found... | ||||
---|---|---|---|---|
| ||||
I have a template function:
void foo(T a) {
}
it modifies the contents of 'a', this works fine if 'a' is a class or array. But it does not work if 'a' is a struct.
This is due to the different methods of passing that D uses, it passes arrays and classes by reference and structs by copying-in.
The solution is to change the function to
void foo(inout T a) {
}
now it works for structs, BUT!, it also allows this function to modify the array/class reference.
If 'in' enforced const, then as soon as I tried to use this function with a struct it would have given an error.
Regan.
--
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
|
July 04, 2004 Re: another bug that 'in' enforcing 'const' would have found... | ||||
---|---|---|---|---|
| ||||
Posted in reply to Regan Heath | Coming from C++, it is one of the biggest obstacles to stay aware that struct and classes behave differently. Writing a template that works for both would be really difficult in most cases.
I agree with you, though, that the behavior of ""/"in"/"out"/"inout" arguments leaves room for improvement and clarification.
Regan Heath wrote:
> I have a template function:
>
> void foo(T a) {
> }
>
> it modifies the contents of 'a', this works fine if 'a' is a class or array. But it does not work if 'a' is a struct.
>
> This is due to the different methods of passing that D uses, it passes arrays and classes by reference and structs by copying-in.
>
> The solution is to change the function to
>
> void foo(inout T a) {
> }
>
> now it works for structs, BUT!, it also allows this function to modify the array/class reference.
>
> If 'in' enforced const, then as soon as I tried to use this function with a struct it would have given an error.
>
> Regan.
>
|
July 04, 2004 Re: another bug that 'in' enforcing 'const' would have found... | ||||
---|---|---|---|---|
| ||||
Posted in reply to Regan Heath | Regan Heath wrote: > I have a template function: > > void foo(T a) { > } > > it modifies the contents of 'a', this works fine if 'a' is a class or array. But it does not work if 'a' is a struct. > > This is due to the different methods of passing that D uses, it passes arrays and classes by reference and structs by copying-in. > > The solution is to change the function to > > void foo(inout T a) { > } > > now it works for structs, BUT!, it also allows this function to modify the array/class reference. What I think is the showstopper is that out and inout parameters can't be rvalues. > If 'in' enforced const, then as soon as I tried to use this function with a struct it would have given an error. An awful, terrible kludge comes to mind. Maybe it will tide you over. // Template that delegates to some other template function, but // drops 'inout'ness for object types. public template RefThing(alias Template) { template RefThing(T) { alias Template!(T) RefThing; } template RefThing(T : Object) { void RefThing(T t) { // the local variable t can be used as an inout return Template!(T)(t); } } } private template FooHelper(T) { void FooHelper(inout T t) { /* Do the actual work */ } } alias RefThing!(FooHelper) Foo; -- andy |
July 05, 2004 Re: another bug that 'in' enforcing 'const' would have found... | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andy Friesen | "Andy Friesen" <andy@ikagames.com> wrote in message news:cc9ia5$1ppc$1@digitaldaemon.com... > What I think is the showstopper is that out and inout parameters can't be rvalues. void foo(inout int x) { x += 3; } ... foo(1 + y); What does it mean to assign a value to 1+y? |
July 05, 2004 Re: another bug that 'in' enforcing 'const' would have found... | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | On Mon, 5 Jul 2004 02:57:37 -0700, Walter <newshound@digitalmars.com> wrote: > "Andy Friesen" <andy@ikagames.com> wrote in message > news:cc9ia5$1ppc$1@digitaldaemon.com... >> What I think is the showstopper is that out and inout parameters can't >> be rvalues. > > void foo(inout int x) { x += 3; } > ... > foo(1 + y); > > What does it mean to assign a value to 1+y? x == 1+y; x+3 == 1+y+3; if you increment both x and y by 3 the statement x == 1+y stays equivalent. so you cannot increment '1' but you could increment 'y' not sure if it makes any sense, or would be any use.. but you could. Perhaps someone with a maths background can make some sense of this? Regan. -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/ |
July 05, 2004 Re: another bug that 'in' enforcing 'const' would have found... | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | Walter wrote:
> "Andy Friesen" <andy@ikagames.com> wrote in message
> news:cc9ia5$1ppc$1@digitaldaemon.com...
>
>>What I think is the showstopper is that out and inout parameters can't
>>be rvalues.
>
> void foo(inout int x) { x += 3; }
> ...
> foo(1 + y);
>
> What does it mean to assign a value to 1+y?
I was referring to rvalues of reference types.
struct S { int x; }
class C {
int x;
static C _inst;
static C getInst() { return _inst; }
}
template Foo(T) {
void Foo(inout T t) { t.x = 0; }
}
This will work for both types C and S, but it at the expense of making this illegal:
Foo!(C)(c.getInst());
-- andy
|
Copyright © 1999-2021 by the D Language Foundation