www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Optional out parameter of function

reply Joseph Rushton Wakeling <joseph.wakeling webdrake.net> writes:
Suppose that I have an "out" parameter in a function:

     int foo(in int i, out int j)
     {
         j = /* something */;
         return /* whatever */;
     }

Is there any way to mark that out parameter as optional, i.e. so that it only 
gets written to/used if a corresponding parameter is passed to the function?

The goal would be to be able to write e.g.

     int i, j;
     foo(i);     // no need to worry about j
     foo(i, j);  // this time j gets written to

It would be easy to write a wrapper function,

     int foo(in int i)
     {
         int j;
         return foo(i, j);
     }

... but I'm wondering if there is a way to make the out parameter optional 
without doing this.

The use-case I'm thinking of is e.g. for a reporting variable that can be used 
to track some kind of function behaviour, but which one doesn't necessarily 
always want to bother measuring.
Nov 26 2013
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Joseph Rushton Wakeling:

 Suppose that I have an "out" parameter in a function:

     int foo(in int i, out int j)
     {
         j = /* something */;
         return /* whatever */;
     }

 Is there any way to mark that out parameter as optional, i.e. 
 so that it only gets written to/used if a corresponding 
 parameter is passed to the function?
One simple solution is to define two overloaded functions, one with and one without the j argument. If you want a single function, dropping out you can write: int foo(size_t N)(in int i, int[N] j...) if (N < 2) { static if (N == 1) j[0] = i; return i; } void main() { auto r1 = foo(1); int x; auto r2 = foo(1, x); } Bye, bearophile
Nov 26 2013
parent reply Joseph Rushton Wakeling <joseph.wakeling webdrake.net> writes:
On 26/11/13 16:44, bearophile wrote:
 If you want a single function, dropping out you can write:

 int foo(size_t N)(in int i, int[N] j...)
 if (N < 2) {
      static if (N == 1)
          j[0] = i;
      return i;
 }
That's a nice thought ... ! Thank you. :-)
Nov 27 2013
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Joseph Rushton Wakeling:

 That's a nice thought ... !  Thank you. :-)
It's useless code, you can't have ref variadic, sorry. Bye, bearophile
Nov 27 2013
next sibling parent Joseph Rushton Wakeling <joseph.wakeling webdrake.net> writes:
On 27/11/13 10:45, bearophile wrote:
 It's useless code, you can't have ref variadic, sorry.
Ack. :-( I just tried it out myself and found the same thing.
Nov 27 2013
prev sibling next sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Wednesday, November 27, 2013 10:57:42 Joseph Rushton Wakeling wrote:
 On 27/11/13 10:45, bearophile wrote:
 It's useless code, you can't have ref variadic, sorry.
Ack. :-( I just tried it out myself and found the same thing.
Personally, I think that it's by far the best approach to just do int foo(int i) { int j; return foo(i, j); } It's clean, and I really don't see a big problem with it. But if you _really_ don't want to do that, you can always create a dummy variable and do something like int dummy; int foo(int i, out int j = dummy) { ... } But I'd advise against it, since it strikes me as rather messy, and I really don't see any problem with just creating a wrapper function. It's the kind of thing that you already have to pretty much any time that you try and have a function accept const ref for an efficiency boost, since ref doesn't accept rvalues. A bit annoying perhaps, but not a big deal. - Jonathan M Davis
Nov 27 2013
parent reply "monarch_dodra" <monarchdodra gmail.com> writes:
On Wednesday, 27 November 2013 at 10:16:13 UTC, Jonathan M Davis 
wrote:
 On Wednesday, November 27, 2013 10:57:42 Joseph Rushton 
 Wakeling wrote:
 On 27/11/13 10:45, bearophile wrote:
 It's useless code, you can't have ref variadic, sorry.
Ack. :-( I just tried it out myself and found the same thing.
Personally, I think that it's by far the best approach to just do int foo(int i) { int j; return foo(i, j); } It's clean, and I really don't see a big problem with it. But if you _really_ don't want to do that, you can always create a dummy variable and do something like int dummy; int foo(int i, out int j = dummy) { ... } But I'd advise against it, since it strikes me as rather messy, and I really don't see any problem with just creating a wrapper function. It's the kind of thing that you already have to pretty much any time that you try and have a function accept const ref for an efficiency boost, since ref doesn't accept rvalues. A bit annoying perhaps, but not a big deal. - Jonathan M Davis
Interesting trick. That said, doing this (should) also mean you can't use foo in a pure context, since it means the caller needs to access the global dummy (although that seems to work right now).
Nov 27 2013
parent reply Joseph Rushton Wakeling <joseph.wakeling webdrake.net> writes:
On 27/11/13 12:14, monarch_dodra wrote:
 Interesting trick. That said, doing this (should) also mean you can't use foo
in
 a pure context, since it means the caller needs to access the global dummy
 (although that seems to work right now).
Should be OK in a struct/class method context, if dummy is an internal variable.
Nov 27 2013
parent reply "monarch_dodra" <monarchdodra gmail.com> writes:
On Wednesday, 27 November 2013 at 11:20:59 UTC, Joseph Rushton 
Wakeling wrote:
 On 27/11/13 12:14, monarch_dodra wrote:
 Interesting trick. That said, doing this (should) also mean 
 you can't use foo in
 a pure context, since it means the caller needs to access the 
 global dummy
 (although that seems to work right now).
Should be OK in a struct/class method context, if dummy is an internal variable.
That wouldn't work, because you'd need "this" to refer said dummy variable. Even if it worked, you'd bloat all instances of your struct/class just for dummy data :/
Nov 27 2013
parent Joseph Rushton Wakeling <joseph.wakeling webdrake.net> writes:
On 27/11/13 15:05, monarch_dodra wrote:
 That wouldn't work, because you'd need "this" to refer said dummy variable.
Even
 if it worked, you'd bloat all instances of your struct/class just for dummy
data :/
I'm not saying it's a GOOD idea. :-P
Nov 27 2013
prev sibling parent Joseph Rushton Wakeling <joseph.wakeling webdrake.net> writes:
On 27/11/13 11:15, Jonathan M Davis wrote:
 Personally, I think that it's by far the best approach to just do

       int foo(int i)
       {
           int j;
           return foo(i, j);
       }

 It's clean, and I really don't see a big problem with it.
Yea, that's really the conclusion I had already come to. I emailed the list because I wondered if there was a friendly syntax to enable one to quietly drop a parameter, as one might do for an in-parameter.
Nov 27 2013