Thread overview
Template parameter defaults
May 30, 2011
Johann MacDonagh
May 30, 2011
Jacob Carlborg
May 30, 2011
Johann MacDonagh
May 30, 2011
Jonathan M Davis
May 31, 2011
Jonathan M Davis
May 31, 2011
Simen Kjaeraas
May 30, 2011
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
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
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
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 31, 2011
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
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
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