Const ref and rvalues again...

luka8088 luka8088 at owave.net
Mon Nov 12 15:38:39 PST 2012


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



More information about the Digitalmars-d mailing list