www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Optional type parameter on a template

reply Luis <luis.panadero gmail.com> writes:
I'm trying to make a SparseSet that on function of a optional 
type parameter, could alongside the index set, store other data. 
So I need a way to declare a optional type template parameter.

I prototyped this stuff on run.dlang, but I like know if there is 
a better way :

https://run.dlang.io/is/Uhy5IT

import std;

struct S {
	int x = 0;

     string toString()
     {
         return "S(x="~ x.to!string ~")";
     }
}

struct ZeroOrMore(T = uint, Types...)
     if (__traits(isUnsigned, T))
{
     static assert (Types.length == 0 || Types.length == 1);

     T[] _t;

     static if (Types.length > 0) {
         alias V = Types[0];
         V[] _values;

         void ins(T t, V val)
         {
             this._t ~= t;
             this._values ~= val;
         }
     } else {
         void ins(T t)
         {
             this._t ~= t;
         }
     }
}

void main()
{
     auto s = ZeroOrMore!()();
     // trying to use ZeroOrMore() gives error : struct 
onlineapp.ZeroOrMore cannot deduce function from argument types 
!()(), candidates are: onlineapp.d(12): ZeroOrMore(T = uint, 
Types...)
     s.ins(456);

     auto s2 = ZeroOrMore!(uint, S)();
     s2.ins(123, S(666));

     writeln(s); // ZeroOrMore!uint([456])
     writeln(s2); // ZeroOrMore!(uint, S)([123], [S(x=666)])
}
May 12 2020
next sibling parent Luis <luis.panadero gmail.com> writes:
Sorry ... wrong link. This is the correct : 
https://run.dlang.io/is/D2iCP0
May 12 2020
prev sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Tuesday, 12 May 2020 at 20:36:22 UTC, Luis wrote:
 I'm trying to make a SparseSet that on function of a optional 
 type parameter, could alongside the index set, store other 
 data. So I need a way to declare a optional type template 
 parameter.
A default argument of void is a common way to do it template foo(T = void) { static if(is(T == void)) { not given } else { use T } }
     // trying to use ZeroOrMore() gives error : struct 
 onlineapp.ZeroOrMore cannot deduce function from argument types 
 !()(), candidates are: onlineapp.d(12): ZeroOrMore(T = uint, 
 Types...)
Yeah, a template with default parameters must still be instantiated, but you do not need to give the arguments. The ! is a must though (or you could provide some alias but then it has a separate name)
May 12 2020
parent Luis <luis.panadero gmail.com> writes:
On Tuesday, 12 May 2020 at 20:40:35 UTC, Adam D. Ruppe wrote:
 A default argument of void is a common way to do it

 template foo(T = void) {
    static if(is(T == void)) { not given } else { use T }
 }
Perfect! Works as I desired.
May 12 2020