Jump to page: 1 2
Thread overview
how to instantiate explicitly template parameters in struct A(T1){this(T2)(){...}}
May 13, 2013
Timothee Cour
May 13, 2013
Timothee Cour
May 13, 2013
Timon Gehr
May 13, 2013
Timon Gehr
May 14, 2013
Timothee Cour
May 14, 2013
Timothee Cour
May 14, 2013
Juan Manuel Cabo
May 14, 2013
Timothee Cour
May 13, 2013
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
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
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
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
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
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 14, 2013
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 14, 2013
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 14, 2013
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 14, 2013
> 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(){
}
----
« First   ‹ Prev
1 2