June 12, 2017
Is there a way to avoid the following combinatorial explosion of overloaded functions when overloading for lvalue and rvalue arguments? The following may be a bad example because int is cheap to copy. So assume a large datatype instead of int.

import std.stdio;

void foo(in ref int a, in ref int b)
{
    writeln("r, r");
}

void foo(in ref int a, in int b)
{
    writeln("r, i");
}

void foo(in int a, in ref int b)
{
    writeln("i, r");
}

void foo(in int a, in int b)
{
    writeln("i, i");
}

void main()
{
    int a, b;
    foo(a, b);
    foo(a, 0);
    foo(0, a);
    foo(0, 0);
}

June 12, 2017
On Monday, June 12, 2017 20:40:52 Balagopal Komarath via Digitalmars-d-learn wrote:
> Is there a way to avoid the following combinatorial explosion of overloaded functions when overloading for lvalue and rvalue arguments? The following may be a bad example because int is cheap to copy. So assume a large datatype instead of int.
>
> import std.stdio;
>
> void foo(in ref int a, in ref int b)
> {
>      writeln("r, r");
> }
>
> void foo(in ref int a, in int b)
> {
>      writeln("r, i");
> }
>
> void foo(in int a, in ref int b)
> {
>      writeln("i, r");
> }
>
> void foo(in int a, in int b)
> {
>      writeln("i, i");
> }
>
> void main()
> {
>      int a, b;
>      foo(a, b);
>      foo(a, 0);
>      foo(0, a);
>      foo(0, 0);
> }

If you templatize the function, you can use auto ref. e.g.

void foo(T)(auto ref T a) {..}

or

void foo()(auto ref int a) {...}

and then when the function is instantiated, the instantiation will be ref or non-ref depending on whether an lvalue or rvalue was passed. So you still get the combinatorial explosion of functions, but you don't have to write them manually. Of course, if you're dealing with a virtual function though, you'll have to do it manually, because templated functions can't be virtual. But in cases like that, you could have a protected function which took ref and a public, templated, wrapper function that took auto ref so that you don't have to do it all manually.

In general though, I'd suggest just not using ref to avoid copying unless you know that it's a performance problem.

- Jonathan M Davis