Thread overview
Can't seem to call super constructor if it's a template
Aug 10
Meta
August 10
class A {
    this(T)() {}
}

class B : A {
    this() { super!int(); }
}

Error: found ! when expecting ; following statement

That should work, shouldn't it?
August 10
On Mon, Aug 10, 2020 at 02:37:06PM -0400, Andrei Alexandrescu via Digitalmars-d wrote:
> class A {
>     this(T)() {}
> }
> 
> class B : A {
>     this() { super!int(); }
> }
> 
> Error: found ! when expecting ; following statement
> 
> That should work, shouldn't it?

Looks like a bug. :-)


T

-- 
Caffeine underflow. Brain dumped.
August 10
On Monday, 10 August 2020 at 18:37:06 UTC, Andrei Alexandrescu wrote:
> class A {
>     this(T)() {}
> }
>
> class B : A {
>     this() { super!int(); }
> }
>
> Error: found ! when expecting ; following statement
>
> That should work, shouldn't it?

Unfortunately this doesn't work either:

class A {
    this(T)() {}
}

class B : A {
    //Error: constructor onlineapp.B.this no match for implicit super() call in constructor
    this()
    {
        super.__ctor!int();
    }
}


Because super.__ctor apparently doesn't count as a call to the superclass's constructor for the flow analysis.
August 10
On 8/10/20 2:37 PM, Andrei Alexandrescu wrote:
> class A {
>      this(T)() {}
> }
> 
> class B : A {
>      this() { super!int(); }
> }
> 
> Error: found ! when expecting ; following statement
> 
> That should work, shouldn't it?

https://issues.dlang.org/show_bug.cgi?id=18886

Though technically it's asking for a different solution.

Possibly related:

https://issues.dlang.org/show_bug.cgi?id=13635


-Steve
August 11
On Monday, 10 August 2020 at 18:37:06 UTC, Andrei Alexandrescu wrote:
> class A {
>     this(T)() {}
> }
>
> class B : A {
>     this() { super!int(); }
> }
>
> Error: found ! when expecting ; following statement
>
> That should work, shouldn't it?

I'm not sure. A problem for example is that the class constructors must have a physical address for TypeInfoClass and _d_new_class
August 12
On Monday, 10 August 2020 at 18:37:06 UTC, Andrei Alexandrescu wrote:
> class A {
>     this(T)() {}
> }
>
> class B : A {
>     this() { super!int(); }
> }
>
> Error: found ! when expecting ; following statement
>
> That should work, shouldn't it?

It is not possible to call cobstructors with explicit template parameters. There was documentation note about that from what I remember, though for some reason I can't find yet.

Reason for that may be the case where you have templated class with templated constructor. How would user pass template args to class itself and then to constructor?
August 12
On 8/12/20 2:22 AM, Alexandru Ermicioi wrote:
> On Monday, 10 August 2020 at 18:37:06 UTC, Andrei Alexandrescu wrote:
>> class A {
>>     this(T)() {}
>> }
>>
>> class B : A {
>>     this() { super!int(); }
>> }
>>
>> Error: found ! when expecting ; following statement
>>
>> That should work, shouldn't it?
> 
> It is not possible to call cobstructors with explicit template parameters. There was documentation note about that from what I remember, though for some reason I can't find yet.
> 
> Reason for that may be the case where you have templated class with templated constructor. How would user pass template args to class itself and then to constructor?

A derived class doesn't have to pass template parameters to the base type. super!T should be unambiguous.

It's true that a templated constructor with explicit parameters couldn't be created with that constructor without adding some syntax mechanism for it. But it could be derived from.

-Steve
August 12
On Wednesday, 12 August 2020 at 11:10:42 UTC, Steven Schveighoffer wrote:
> On 8/12/20 2:22 AM, Alexandru Ermicioi wrote:
>> On Monday, 10 August 2020 at 18:37:06 UTC, Andrei Alexandrescu wrote:
>>> class A {
>>>     this(T)() {}
>>> }
>>>
>>> class B : A {
>>>     this() { super!int(); }
>>> }
>>>
>>> Error: found ! when expecting ; following statement
>>>
>>> That should work, shouldn't it?
>> 
>> It is not possible to call cobstructors with explicit template parameters. There was documentation note about that from what I remember, though for some reason I can't find yet.
>> 
>> Reason for that may be the case where you have templated class with templated constructor. How would user pass template args to class itself and then to constructor?
>
> A derived class doesn't have to pass template parameters to the base type. super!T should be unambiguous.

Indeed it should, but that would be another edge case that would be usable just in derived classes and not in any other location, won't it?

Imho, it would make more confusing for new joiner, where he would expect same functionality to be available also for new expressions or during allocation using std.experimental.

I think we should not allow just this use case, but rather think on how can we chain multilple sets of template args, which would solve the thing also for new expressions too.

- Alex
August 12
On Wednesday, 12 August 2020 at 11:32:19 UTC, Alexandru Ermicioi wrote:
>
> I think we should not allow just this use case, but rather think on how can we chain multilple sets of template args, which would solve the thing also for new expressions too.
>
> - Alex

Btw, this issue is not present only for constructors, it is also a problem for eponymous templates, where you have nested templates with same name as root template and with some args. You just can't simply pass template args for second eponymous template, since D allows only one set of template args to be passed on invocation site.

Workaround for that is only aliasing of first invocation, and then calling the alias with args for nested template

- Alex