www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - how to instantiate explicitly template parameters in struct

reply Timothee Cour <thelastmammoth gmail.com> writes:
While writing DIP40, I came upon the following question:
how to instantiate explicitly template parameters for both the
class/struct AND the constructor?
for example: struct A(T1){this(T2)(){...}}  ? (T2 could be used
somehow inside the ctor body for example)
// auto a=A!double!int(); // CT error
The example is a bit contrived but there could be less contrived ones
where both A and ctor need explicit instantiations.
May 13 2013
next sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Mon, 13 May 2013 16:27:44 -0400, Timothee Cour  
<thelastmammoth gmail.com> wrote:

 While writing DIP40, I came upon the following question:
 how to instantiate explicitly template parameters for both the
 class/struct AND the constructor?
 for example: struct A(T1){this(T2)(){...}}  ? (T2 could be used
 somehow inside the ctor body for example)
 // auto a=A!double!int(); // CT error
 The example is a bit contrived but there could be less contrived ones
 where both A and ctor need explicit instantiations.
Since you can't call the ctor directly [1], this isn't possible in any case, even without a templated struct. What you CAN do is specify a constructing function: struct A(T1) { static A make(T2)(){...} } auto a = A!double.make!int(); -Steve ================== [1] This does work, but is not documented/official AFAIK: struct S { this(T)(int i) {} } void main() { S s; s.__ctor!double(1); }
May 13 2013
parent reply Timothee Cour <thelastmammoth gmail.com> writes:
Thanks!
should that be considered as a limitation, and therefore be fixed?
(for example by documenting the __ctor syntax)?
The static make trick is boilerplate and shouldn't be considered the best way.

On Mon, May 13, 2013 at 3:06 PM, Steven Schveighoffer
<schveiguy yahoo.com> wrote:
 On Mon, 13 May 2013 16:27:44 -0400, Timothee Cour <thelastmammoth gmail.com>
 wrote:

 While writing DIP40, I came upon the following question:
 how to instantiate explicitly template parameters for both the
 class/struct AND the constructor?
 for example: struct A(T1){this(T2)(){...}}  ? (T2 could be used
 somehow inside the ctor body for example)
 // auto a=A!double!int(); // CT error
 The example is a bit contrived but there could be less contrived ones
 where both A and ctor need explicit instantiations.
Since you can't call the ctor directly [1], this isn't possible in any case, even without a templated struct. What you CAN do is specify a constructing function: struct A(T1) { static A make(T2)(){...} } auto a = A!double.make!int(); -Steve ================== [1] This does work, but is not documented/official AFAIK: struct S { this(T)(int i) {} } void main() { S s; s.__ctor!double(1); }
May 13 2013
parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Mon, 13 May 2013 19:04:39 -0400, Timothee Cour  
<thelastmammoth gmail.com> wrote:

 Thanks!
 should that be considered as a limitation, and therefore be fixed?
 (for example by documenting the __ctor syntax)?
 The static make trick is boilerplate and shouldn't be considered the  
 best way.
Well, it's not really boilerplate :) It takes the place of an actual constructor. In other words, you don't also need a this() function. Technically, what we are missing is the name of the constructor. Otherwise, you have nothing to apply the '!' to. As I said, I don't know if __ctor is official, maybe it is already. I know some code in druntime uses it. -Steve
May 13 2013
prev sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 05/13/2013 10:27 PM, Timothee Cour wrote:
 While writing DIP40, I came upon the following question:
 how to instantiate explicitly template parameters for both the
 class/struct AND the constructor?
 for example: struct A(T1){this(T2)(){...}}  ? (T2 could be used
 somehow inside the ctor body for example)
 // auto a=A!double!int(); // CT error
 The example is a bit contrived but there could be less contrived ones
 where both A and ctor need explicit instantiations.
There is a more basic question: How to explicitly pass template arguments to _any_ constructor?
May 13 2013
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 05/14/2013 01:25 AM, Timon Gehr wrote:
 On 05/13/2013 10:27 PM, Timothee Cour wrote:
 While writing DIP40, I came upon the following question:
 how to instantiate explicitly template parameters for both the
 class/struct AND the constructor?
 for example: struct A(T1){this(T2)(){...}}  ? (T2 could be used
 somehow inside the ctor body for example)
 // auto a=A!double!int(); // CT error
 The example is a bit contrived but there could be less contrived ones
 where both A and ctor need explicit instantiations.
There is a more basic question: How to explicitly pass template arguments to _any_ constructor?
(There currently is no documented way.)
May 13 2013
parent reply Timothee Cour <thelastmammoth gmail.com> writes:
A)
The behavior of __ctor (whether or not documented) seems broken / unreliable:

struct A{this(T)(T x){}}

void fun(T){
  auto a=A.__ctor!(int)(1);
}
void main(){
  auto a=A.__ctor!(int)(1); //ok
  fun!int(); //Error: type A is not an expression
}


Is that a bug?

B)
Why not use 'this' instead of '__ctor', and make it documented (and
reliable, ie work in the above case) ?
I don't see how that could create ambiguity, and that would solve the
problem raised in this thread.
May 13 2013
next sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Mon, 13 May 2013 23:34:39 -0400, Timothee Cour  
<thelastmammoth gmail.com> wrote:

 A)
 The behavior of __ctor (whether or not documented) seems broken /  
 unreliable:

 struct A{this(T)(T x){}}

 void fun(T){
   auto a=A.__ctor!(int)(1);
 }
 void main(){
   auto a=A.__ctor!(int)(1); //ok
   fun!int(); //Error: type A is not an expression
 }
__ctor is a 'this' call, it needs a this (BTW, I get different errors than you): struct A{this(T)(T x){}} void fun(T)(){ A a; a.__ctor!(int)(1); } void main(){ A a; a.__ctor!(int)(1); fun!int(); } Not sure how you would do that in one line (and I assume you had a typo in fun(T) since it wasn't valid syntax).
 B)
 Why not use 'this' instead of '__ctor', and make it documented (and
 reliable, ie work in the above case) ?
 I don't see how that could create ambiguity, and that would solve the
 problem raised in this thread.
You could do that. It may have some ambiguous syntax implications. -Steve
May 13 2013
parent Timothee Cour <thelastmammoth gmail.com> writes:
 __ctor is a 'this' call, it needs a this (BTW, I get different errors than
 you):
Seems like not (see my corrected bug in previous post)
 Not sure how you would do that in one line
ditto
 Why not use 'this' instead of '__ctor', and make it documented (and
 reliable, ie work in the above case) ?
 I don't see how that could create ambiguity, and that would solve the
 problem raised in this thread.
You could do that. It may have some ambiguous syntax implications.
I really can't think of any, and I think it would just make sense, given that it'd match the way the function is declared.
May 13 2013
prev sibling parent reply "Juan Manuel Cabo" <juanmanuel.cabo gmail.com> writes:
On Tuesday, 14 May 2013 at 03:34:52 UTC, Timothee Cour wrote:
 A)
 The behavior of __ctor (whether or not documented) seems broken 
 / unreliable:

 struct A{this(T)(T x){}}

 void fun(T){
   auto a=A.__ctor!(int)(1);
 }
 void main(){
   auto a=A.__ctor!(int)(1); //ok
   fun!int(); //Error: type A is not an expression
 }


 Is that a bug?

 B)
 Why not use 'this' instead of '__ctor', and make it documented 
 (and
 reliable, ie work in the above case) ?
 I don't see how that could create ambiguity, and that would 
 solve the
 problem raised in this thread.
I declared fun(T) as fun(T)() with the added parenthesis, and it worked (tested on dmd 2.062 / ubuntu 64bits). The following prints "it works" twice: import std.stdio; struct A { this(T)(T x) { writeln("it works"); } } void fun(T)(){ auto a=A.__ctor!(int)(1); } void main(){ auto a=A.__ctor!(int)(1); //ok fun!int(); //ok too } --jm
May 13 2013
parent reply Timothee Cour <thelastmammoth gmail.com> writes:
 I declared fun(T) as fun(T)() with the added parenthesis, and it
 worked (tested on dmd 2.062 / ubuntu 64bits).
sorry I reduced wrongly. Here's the inconsistency: ---- struct A { this(T)(T x) { } } auto fun1(){ auto a=A.__ctor!(int)(1); //OK return a; } auto fun2(){ // return A.__ctor!(int)(1); //uncomment gives Error: type A is not an expression } void main(){ } ----
May 13 2013
parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Tue, 14 May 2013 00:32:49 -0400, Timothee Cour  
<thelastmammoth gmail.com> wrote:

 I declared fun(T) as fun(T)() with the added parenthesis, and it
 worked (tested on dmd 2.062 / ubuntu 64bits).
sorry I reduced wrongly. Here's the inconsistency: ---- struct A { this(T)(T x) { } } auto fun1(){ auto a=A.__ctor!(int)(1); //OK
This line causes an error message for me: testctor.d(5): Error: need 'this' for 'this' of type 'pure nothrow ref safe A(int x)'
 	return a;
 }
 auto fun2(){	
 //	return A.__ctor!(int)(1); //uncomment gives Error: type A is not an
 expression
Same error for me here: testctor.d(9): Error: need 'this' for 'this' of type 'pure nothrow ref safe A(int x)' I'm using dmd beta candidate, 2.061 does give the same error message you have. Note that you may expect this as you are using an undocumented "feature" :) -Steve
May 14 2013