www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Varargs and default arguments

reply Nick Sabalausky <SeeWebsiteToContactMe semitwist.com> writes:
Ok, D-style varargs can accept a parameter length of zero:

---------------
void foo(T...)(T args) {
     //...
}
foo();
foo(t1, t2);
---------------

Is there any way to stick a param with a default value before that?

---------------
void foo(T...)(string str=null, T args=/+what goes here???+/) {
     //...
}
foo();
foo(str);
foo(str, t1, t2);
---------------

Obviously this can be worked around easily enough by splitting it into 
two overloads ("foo(string str=null)" and "foo(string str, T args)"), 
but is there a way to do it in one?
Oct 06 2015
parent reply anonymous <anonymous example.com> writes:
On Tuesday 06 October 2015 22:01, Nick Sabalausky wrote:

 Ok, D-style varargs can accept a parameter length of zero:
 
 ---------------
 void foo(T...)(T args) {
      //...
 }
 foo();
 foo(t1, t2);
 ---------------
Terminology fun: The spec uses the term "D-style variadic function" for something else yet: `int abc(char c, ...);` -- http://dlang.org/function.html#variadic Yours is technically a "variadic function template", I guess, i.e., a function template that's variadic, not a template of a variadic function.
 Is there any way to stick a param with a default value before that?
 
 ---------------
 void foo(T...)(string str=null, T args=/+what goes here???+/) {
      //...
 }
 foo();
 foo(str);
 foo(str, t1, t2);
 ---------------
 
 Obviously this can be worked around easily enough by splitting it into 
 two overloads ("foo(string str=null)" and "foo(string str, T args)"), 
 but is there a way to do it in one?
You can put an expression tuple ("expression AliasSeq"??) there. T.init is one that always fits T's types. But you could generate one with different values, too. ---- void foo(T...)(string str=null, T args = T.init) { //... } void main() { foo(); foo(""); foo("", 1, 2); } ----
Oct 06 2015
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 10/6/15 4:27 PM, anonymous wrote:
 You can put an expression tuple ("expression AliasSeq"??) there. T.init is
 one that always fits T's types. But you could generate one with different
 values, too.

 ----
 void foo(T...)(string str=null, T args = T.init) {
 	//...
 }
 void main()
 {
 	foo();
 	foo("");
What is T in this case? I wondered, and it is an empty expression tuple (prints out as "()"). Interesting. Note, this doesn't seem to work on 2.067. There are other ways to solve this too: void foo() {return foo(null);} void foo(T...)(string str, T args) {...} I find it quite fascinating that in anonymous' solution, the T.init doesn't ever actually get used! -Steve
Oct 06 2015
parent anonymous <anonymous example.com> writes:
On Wednesday 07 October 2015 02:22, Steven Schveighoffer wrote:

 On 10/6/15 4:27 PM, anonymous wrote:
[...]
 void foo(T...)(string str=null, T args = T.init) {
[...]
 I find it quite fascinating that in anonymous' solution, the T.init 
 doesn't ever actually get used!
It's not used with IFTI, but if you instantiate the template explicitly, the defaults arguments come up. Or rather, they should come up. It doesn't seem to work: ---- void foo(T ...)(T args = T.init) {} void main() { foo!(int, float)(); /* Error: foo (int _param_0, float _param_1) is not callable using argument types () */ } ---- I filed an issue: https://issues.dlang.org/show_bug.cgi?id=15170
Oct 07 2015