Thread overview
another bug that 'in' enforcing 'const' would have found...
Jul 04, 2004
Regan Heath
Jul 04, 2004
Norbert Nemec
Jul 04, 2004
Andy Friesen
Jul 05, 2004
Walter
Jul 05, 2004
Regan Heath
Jul 05, 2004
Andy Friesen
July 04, 2004
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
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
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
"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
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
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