www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Overloading for lvalue and rvalue.

reply Balagopal Komarath <baluks gmail.com> writes:
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);
}
Jun 12 2017
parent Jonathan M Davis via Digitalmars-d-learn writes:
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
Jun 12 2017