www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Template parameter defaults

reply Johann MacDonagh <johann.macdonagh..no spam..gmail.com> writes:
I'm wondering if there's a cleaner way to do this:

class Test(T = uint)
{
     this(string s)
     {
     }
}

void main(string[] argv)
{
     auto a = new Test!()("test");
}

I'd *like* to be able to do this:

auto a = new Test("test");

and:

auto a = new Test!double("test");

The only possibility I see is to do this:

alias Test!() Test2;

But that introduces two types a user has to decide between. Any ideas? 
Am I out of luck here?

Thanks
May 30 2011
next sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2011-05-30 15:42, Johann MacDonagh wrote:
 I'm wondering if there's a cleaner way to do this:

 class Test(T = uint)
 {
 this(string s)
 {
 }
 }

 void main(string[] argv)
 {
 auto a = new Test!()("test");
 }

 I'd *like* to be able to do this:

 auto a = new Test("test");

 and:

 auto a = new Test!double("test");

 The only possibility I see is to do this:

 alias Test!() Test2;

 But that introduces two types a user has to decide between. Any ideas?
 Am I out of luck here?

 Thanks

If you want to use the default parameter I think you have to do this: auto a = new Test!()("test"); -- /Jacob Carlborg
May 30 2011
parent Johann MacDonagh <johann.macdonagh..no spam..gmail.com> writes:
On 5/30/2011 10:12 AM, Jacob Carlborg wrote:
 If you want to use the default parameter I think you have to do this:

 auto a = new Test!()("test");

Yeah, that's the best I could come up with too :( I suppose users can alias it if necessary. Thanks!
May 30 2011
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On 2011-05-30 06:42, Johann MacDonagh wrote:
 I'm wondering if there's a cleaner way to do this:
 
 class Test(T = uint)
 {
      this(string s)
      {
      }
 }
 
 void main(string[] argv)
 {
      auto a = new Test!()("test");
 }
 
 I'd *like* to be able to do this:
 
 auto a = new Test("test");
 
 and:
 
 auto a = new Test!double("test");
 
 The only possibility I see is to do this:
 
 alias Test!() Test2;
 
 But that introduces two types a user has to decide between. Any ideas?
 Am I out of luck here?

The alternative is to create a helper function outside of the class which calls the constructor. Unlike the class/struct, the function is able to use type inference, and so you can skip the !() part. For instance, that's what std.container.redBackTree does for RedBlackTree. In the case where you want a default argument, the function will use the default argument or you can give it the type directly. But you can't do that with a class/struct, because you don't get any type inference when instantiating a class/struct. - Jonathan M Davis
May 30 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Mon, 30 May 2011 09:42:53 -0400, Johann MacDonagh  
<johann.macdonagh..no spam..gmail.com> wrote:

 I'm wondering if there's a cleaner way to do this:

 class Test(T = uint)
 {
      this(string s)
      {
      }
 }

 void main(string[] argv)
 {
      auto a = new Test!()("test");
 }

 I'd *like* to be able to do this:

 auto a = new Test("test");

 and:

 auto a = new Test!double("test");

 The only possibility I see is to do this:

 alias Test!() Test2;

 But that introduces two types a user has to decide between. Any ideas?  
 Am I out of luck here?

Currently, you can omit the template args only in the case of IFTI (Implicit Function Template Instantiation) which actually deduces your template arguments based on the function call. I'd argue actually, that IFTI should be extended to constructors: class Test(T) { this(T t) {} } T t; auto a = new Test(1); static assert(is(typeof(a) == Test!int)); Which would also cover your case. This should be a no-brainer since a constructor call is almost identical in nature to a function call. For sure the overload resolution is the same. I thought there was a bugzilla entry for this, but I couldn't find it with some simple searches, anyone know of one? If not, I'll file one. -Steve
May 31 2011
prev sibling next sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On 2011-05-31 10:49, Steven Schveighoffer wrote:
 On Mon, 30 May 2011 09:42:53 -0400, Johann MacDonagh
 
 <johann.macdonagh..no spam..gmail.com> wrote:
 I'm wondering if there's a cleaner way to do this:
 
 class Test(T = uint)
 {
 
 this(string s)
 {
 }
 
 }
 
 void main(string[] argv)
 {
 
 auto a = new Test!()("test");
 
 }
 
 I'd *like* to be able to do this:
 
 auto a = new Test("test");
 
 and:
 
 auto a = new Test!double("test");
 
 The only possibility I see is to do this:
 
 alias Test!() Test2;
 
 But that introduces two types a user has to decide between. Any ideas?
 Am I out of luck here?

Currently, you can omit the template args only in the case of IFTI (Implicit Function Template Instantiation) which actually deduces your template arguments based on the function call.

I'm not aware of a bugzilla entry on it. I just know that it doesn't work. - Jonathan M Davis
 
 I'd argue actually, that IFTI should be extended to constructors:
 
 class Test(T)
 {
 this(T t) {}
 }
 
 T t;
 auto a = new Test(1);
 
 static assert(is(typeof(a) == Test!int));
 
 Which would also cover your case.
 
 This should be a no-brainer since a constructor call is almost identical
 in nature to a function call. For sure the overload resolution is the
 same.
 
 I thought there was a bugzilla entry for this, but I couldn't find it with
 some simple searches, anyone know of one? If not, I'll file one.
 
 -Steve

May 31 2011
prev sibling parent "Simen Kjaeraas" <simen.kjaras gmail.com> writes:
On Tue, 31 May 2011 19:49:24 +0200, Steven Schveighoffer  
<schveiguy yahoo.com> wrote:

 Currently, you can omit the template args only in the case of IFTI  
 (Implicit Function Template Instantiation) which actually deduces your  
 template arguments based on the function call.

 I'd argue actually, that IFTI should be extended to constructors:

 class Test(T)
 {
     this(T t) {}
 }

 T t;
 auto a = new Test(1);

 static assert(is(typeof(a) == Test!int));

 Which would also cover your case.

 This should be a no-brainer since a constructor call is almost identical  
 in nature to a function call.  For sure the overload resolution is the  
 same.

 I thought there was a bugzilla entry for this, but I couldn't find it  
 with some simple searches, anyone know of one?  If not, I'll file one.

I've filed one at some point. Actually, looking at it, this was for static opCall for structs. The idea is still the same, though. http://d.puremagic.com/issues/show_bug.cgi?id=1997 -- Simen
May 31 2011