What about making this a default behavior and introducing a new keyword if the function wants to modify the argument but it is not ref (pass by value) ? The reason I think that this should be a default behavior because not many functions actually modify their arguments and so it leaves a lot of space for optimization.

For example:

void f (int x, val int y, ref int z) {
  x = 1; // x is not copied
         // compiler throws an error, x is not passed by value
         // and therefor could not / should not be changed
  y = 2; // ok, y is copied
  z = 3; // ok, z is a reference
}

On 18.10.2012 5:07, Malte Skarupke wrote:
Hello,

I realize that this has been discussed before, but so far there is no
solution and this really needs to be a high priority:

We need a way for a function to declare that it doesn't want it's
argument to be copied, but it also doesn't care whether the argument is
an rvalue or an lvalue.

The C++ way of doing this would be to declare the argument as a const &.
Apparently it is not desired that we do the same thing for const ref.

Currently, if you want that behavior, you have to write 2^n permutations
of your function, with n being the number of arguments that the function
takes.

Here's my attempt at passing a struct to a function that takes three
arguments without the struct being copied:

int copyCounter = 0;
struct CopyCounter
{
this(this) { ++copyCounter; }
}
void takeThree(ref in CopyCounter a, ref in CopyCounter b, ref in
CopyCounter c)
{
writeln("took three");
}
void takeThree(in CopyCounter a, ref in CopyCounter b, ref in
CopyCounter c)
{
takeThree(a, b, c);
}
void takeThree(ref in CopyCounter a, in CopyCounter b, ref in
CopyCounter c)
{
takeThree(a, b, c);
}
void takeThree(ref in CopyCounter a, ref in CopyCounter b, in
CopyCounter c)
{
takeThree(a, b, c);
}
void takeThree(in CopyCounter a, in CopyCounter b, ref in CopyCounter c)
{
takeThree(a, b, c);
}
void takeThree(in CopyCounter a, ref in CopyCounter b, in CopyCounter c)
{
takeThree(a, b, c);
}
void takeThree(ref in CopyCounter a, in CopyCounter b, in CopyCounter c)
{
takeThree(a, b, c);
}
void takeThree(in CopyCounter a, in CopyCounter b, in CopyCounter c)
{
takeThree(a, b, c);
}
static CopyCounter createCopyCounter()
{
return CopyCounter();
}
void main()
{
CopyCounter first;
CopyCounter second;
CopyCounter third;
takeThree(first, second, third);
takeThree(createCopyCounter(), second, createCopCounter());
assert(copyCounter == 0); // yay, works
}


My propsed solution is this:
- Make functions that take "ref in" arguments also accept rvalues.
- The user can still provide an overload that accepts an rvalue, using
the "in" keyword, and that one will be preferred over the "ref in" version.


What do you think?

Malte

Reply via email to