Thread overview
How to instantiate a template struct with a template constructor without relying on auto deduction?
Feb 21, 2018
ParticlePeter
Feb 21, 2018
Simen Kjærås
Feb 21, 2018
ParticlePeter
Feb 21, 2018
ixid
Feb 21, 2018
Simen Kjærås
Feb 21, 2018
ixid
February 21, 2018
struct Foo(T) {
  T bar;
  this(S)(S s) {
    bar = convert(s);
  }
}

auto foo = Foo!int(some_float);


this works because S is deduced as typeof(some_float), but how would I instantiate the struct without relying on auto deduction?

Suppose we would have this kind of constructor where auto deduction is not possible:

  this(int n)(float f) {
    static foreach( i; 0..n) { do_some_ctfe_magic;}
  }

How to instantiate Foo then?
February 21, 2018
On Wednesday, 21 February 2018 at 14:11:10 UTC, ParticlePeter wrote:
> struct Foo(T) {
>   T bar;
>   this(S)(S s) {
>     bar = convert(s);
>   }
> }
>
> auto foo = Foo!int(some_float);
>
>
> this works because S is deduced as typeof(some_float), but how would I instantiate the struct without relying on auto deduction?
>
> Suppose we would have this kind of constructor where auto deduction is not possible:
>
>   this(int n)(float f) {
>     static foreach( i; 0..n) { do_some_ctfe_magic;}
>   }
>
> How to instantiate Foo then?

No can do. The solution is to use a factory function:

struct Foo(T) {
    static Foo create(int n)(float f) {
        Foo result;
        static foreach( i; 0..n) { do_some_ctfe_magic;}
        return result;
    }
}

--
  Simen
February 21, 2018
On Wednesday, 21 February 2018 at 14:11:10 UTC, ParticlePeter wrote:
> struct Foo(T) {
>   T bar;
>   this(S)(S s) {
>     bar = convert(s);
>   }
> }
>
> auto foo = Foo!int(some_float);
>
>
> this works because S is deduced as typeof(some_float), but how would I instantiate the struct without relying on auto deduction?
>
> Suppose we would have this kind of constructor where auto deduction is not possible:
>
>   this(int n)(float f) {
>     static foreach( i; 0..n) { do_some_ctfe_magic;}
>   }
>
> How to instantiate Foo then?

I do not understand what is happening here, I tried to wrote what I thought would be the answer. If someone could explain that would be great. I wrote this code:

struct Foo2(T, S) {
  T bar;
  this(S s) {
    bar = s.to!T;
  }
}

void main() {
	float some_float = 0.5f;
	int some_int = 1;

	auto foo1 = Foo2!(int, float)(some_float);    // Compiles, OK!
	auto foo2 = Foo2!(int, float)(some_int);      // Compiles, wat?
}

February 21, 2018
On Wednesday, 21 February 2018 at 14:29:38 UTC, ixid wrote:
> I do not understand what is happening here, I tried to wrote what I thought would be the answer. If someone could explain that would be great. I wrote this code:
>
> struct Foo2(T, S) {
>   T bar;
>   this(S s) {
>     bar = s.to!T;
>   }
> }
>
> void main() {
> 	float some_float = 0.5f;
> 	int some_int = 1;
>
> 	auto foo1 = Foo2!(int, float)(some_float);    // Compiles, OK!
> 	auto foo2 = Foo2!(int, float)(some_int);      // Compiles, wat?
> }

int n = 1;
float f = n; // Basically this.

Foo2!(int, float) expects a float, and ints are implicitly convertible to float.

--
  Simen
February 21, 2018
On Wednesday, 21 February 2018 at 14:42:56 UTC, Simen Kjærås wrote:
> On Wednesday, 21 February 2018 at 14:29:38 UTC, ixid wrote:
>> I do not understand what is happening here, I tried to wrote what I thought would be the answer. If someone could explain that would be great. I wrote this code:
>>
>> struct Foo2(T, S) {
>>   T bar;
>>   this(S s) {
>>     bar = s.to!T;
>>   }
>> }
>>
>> void main() {
>> 	float some_float = 0.5f;
>> 	int some_int = 1;
>>
>> 	auto foo1 = Foo2!(int, float)(some_float);    // Compiles, OK!
>> 	auto foo2 = Foo2!(int, float)(some_int);      // Compiles, wat?
>> }
>
> int n = 1;
> float f = n; // Basically this.
>
> Foo2!(int, float) expects a float, and ints are implicitly convertible to float.
>
> --
>   Simen

Ah yes, that was silly of me to forget. Thanks!
February 21, 2018
On Wednesday, 21 February 2018 at 14:29:31 UTC, Simen Kjærås wrote:
> On Wednesday, 21 February 2018 at 14:11:10 UTC, ParticlePeter wrote:
>> struct Foo(T) {
>>   T bar;
>>   this(S)(S s) {
>>     bar = convert(s);
>>   }
>> }
>>
>> auto foo = Foo!int(some_float);
>>
>>
>> this works because S is deduced as typeof(some_float), but how would I instantiate the struct without relying on auto deduction?
>>
>> Suppose we would have this kind of constructor where auto deduction is not possible:
>>
>>   this(int n)(float f) {
>>     static foreach( i; 0..n) { do_some_ctfe_magic;}
>>   }
>>
>> How to instantiate Foo then?
>
> No can do. The solution is to use a factory function:

Feared the same, thanks.

> struct Foo(T) {
>     static Foo create(int n)(float f) {
>         Foo result;
>         static foreach( i; 0..n) { do_some_ctfe_magic;}
>         return result;
>     }
> }
>
> --
>   Simen

I will consider this, actually I use something quite close, but my create is not static and does not return anything. It simply initializes the struct after it has been constructed with the default ctor. The templated user ctor would have been nice, though.