Thread overview
template auto instantiation when parameters empty
May 04, 2016
Erik Smith
May 05, 2016
Andrea Fontana
May 05, 2016
Erik Smith
May 08, 2016
Jonathan M Davis
May 04, 2016
I want to have a struct template auto instantiate when the template parameters are defaulted or missing.  Example:

struct Resource(T=int) {
    static auto create() {return Resource(null);}
    this(string s) {}
}

auto resource = Resource.create;

As a plain struct it works, but not as a template:

struct Resource {   // works
struct Resource() {  // fails
struct Resource(T=int) {  // fails

At the call site, this works, but I'm hoping for a few less symbols:

auto resource = Resource!().create;

Any ideas?

May 05, 2016
On Wednesday, 4 May 2016 at 22:10:16 UTC, Erik Smith wrote:
> Any ideas?

Using an alias could be a solution.

May 05, 2016
On 5/5/16 12:10 AM, Erik Smith wrote:
> I want to have a struct template auto instantiate when the template
> parameters are defaulted or missing.  Example:
>
> struct Resource(T=int) {
>      static auto create() {return Resource(null);}
>      this(string s) {}
> }
>
> auto resource = Resource.create;
>
> As a plain struct it works, but not as a template:
>
> struct Resource {   // works
> struct Resource() {  // fails
> struct Resource(T=int) {  // fails
>
> At the call site, this works, but I'm hoping for a few less symbols:
>
> auto resource = Resource!().create;
>
> Any ideas?

Instead of static method, use an external factory method:

static auto createResource(T = int)()
{
   return Resource!T(null);
}

And I wouldn't bother with making Resource's T have a default, as you'd still have to instantiate it with Resource!() to get the default.

-Steve
May 05, 2016
On Thursday, 5 May 2016 at 16:12:40 UTC, Steven Schveighoffer wrote:
> On 5/5/16 12:10 AM, Erik Smith wrote:
>> I want to have a struct template auto instantiate when the template
>> parameters are defaulted or missing.  Example:
>>
>> struct Resource(T=int) {
>>      static auto create() {return Resource(null);}
>>      this(string s) {}
>> }
>>
>> auto resource = Resource.create;
>>
>> As a plain struct it works, but not as a template:
>>
>> struct Resource {   // works
>> struct Resource() {  // fails
>> struct Resource(T=int) {  // fails
>>
>> At the call site, this works, but I'm hoping for a few less symbols:
>>
>> auto resource = Resource!().create;
>>
>> Any ideas?
>
> Instead of static method, use an external factory method:
>
> static auto createResource(T = int)()
> {
>    return Resource!T(null);
> }
>
> And I wouldn't bother with making Resource's T have a default, as you'd still have to instantiate it with Resource!() to get the default.
>
> -Steve

Alias works at the cost of adding a 2nd type name:

alias Res = Resource!();
auto res  = Res.create

The other problem is that the alias definition by itself instantiates, which I can't afford.

I have createResource() now, it just doesn't fit well with the rest of the calling styles.

There is also this approach, which might be slightly more idiomatic

struct Resource(T) {}
struct Policy {}

auto create(alias T)() {
    T!Policy r;
    return r;
}

auto r = create!Resource;





May 05, 2016
On 5/5/16 6:50 PM, Erik Smith wrote:
>
> Alias works at the cost of adding a 2nd type name:
>
> alias Res = Resource!();
> auto res  = Res.create
>
> The other problem is that the alias definition by itself instantiates,
> which I can't afford.
>
> I have createResource() now, it just doesn't fit well with the rest of
> the calling styles.
>
> There is also this approach, which might be slightly more idiomatic
>
> struct Resource(T) {}
> struct Policy {}
>
> auto create(alias T)() {
>      T!Policy r;
>      return r;
> }
>
> auto r = create!Resource;

I believe factory external IFTI functions are quite idiomatic. They are all over phobos.

-Steve
May 08, 2016
On Thursday, May 05, 2016 19:09:01 Steven Schveighoffer via Digitalmars-d- learn wrote:
> On 5/5/16 6:50 PM, Erik Smith wrote:
> > Alias works at the cost of adding a 2nd type name:
> >
> > alias Res = Resource!();
> > auto res  = Res.create
> >
> > The other problem is that the alias definition by itself instantiates, which I can't afford.
> >
> > I have createResource() now, it just doesn't fit well with the rest of
> > the calling styles.
> >
> > There is also this approach, which might be slightly more idiomatic
> >
> > struct Resource(T) {}
> > struct Policy {}
> >
> > auto create(alias T)() {
> >
> >      T!Policy r;
> >      return r;
> >
> > }
> >
> > auto r = create!Resource;
>
> I believe factory external IFTI functions are quite idiomatic. They are all over phobos.

When dealing with the creation of objects that are templatized, they're often practically required for using the object to be sane - particularly when the constructor itself needs to be further templatized. And since IFTI only works with functions, if you want something similar with templated types, wrapping the construction in a function to get IFTI is pretty much your only option if you want to avoid requiring explicit instantiations.

- Jonathan M Davis