Overloading for lvalue and rvalue.

Jonathan M Davis via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Mon Jun 12 13:58:23 PDT 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



More information about the Digitalmars-d-learn mailing list