Thread overview
aliasing superclass constructors
Dec 26, 2012
Nick Treleaven
Dec 26, 2012
Maxim Fomin
Dec 26, 2012
Nick Treleaven
Dec 26, 2012
Maxim Fomin
December 26, 2012
Hi,
Is there an easy way to forward/expose all the constructors of a parent class? Just curious. Here are my attempts:

class EFoo : Exception
{
	//alias typeof(super).this this;	// line 12
	//alias typeof(super).__ctor __ctor;	// line 13
}

uncommenting line 12:
superthis.d(12): Error: identifier expected following '.' instead of 'this'
superthis.d(12): Error: no identifier for declarator typeof(super)
superthis.d(12): Error: semicolon expected to close alias declaration
superthis.d(12): Error: found 'this' when expecting '('
superthis.d(12): Error: basic type expected, not ;
superthis.d(12): Error: found ';' when expecting ')'
superthis.d(17): Error: semicolon expected following function declaration
Compilation failed.

uncommenting line 13:
superthis.d(13): Error: this is not a type

I've got a mixin to work though:

class EFoo : Exception
{
	mixin SuperCtors;
}

mixin template SuperCtors()
{
	this(T...)(T args)
	if (__traits(compiles, {new typeof(super)(args);}))
	{super(args);}
}

But it would be nicer if an alias statement could work to avoid defining the mixin in every project that needs it.

Partly I'm interested in this as I'm wondering if 'alias this' conflicts with 'normal' alias syntax when aliasing constructors.
December 26, 2012
On Wednesday, 26 December 2012 at 14:38:45 UTC, Nick Treleaven wrote:
> Hi,
> Is there an easy way to forward/expose all the constructors of a parent class? Just curious. Here are my attempts:
>
> class EFoo : Exception
> {
> 	//alias typeof(super).this this;	// line 12
> 	//alias typeof(super).__ctor __ctor;	// line 13
> }
>
> uncommenting line 12:
> superthis.d(12): Error: identifier expected following '.' instead of 'this'
> superthis.d(12): Error: no identifier for declarator typeof(super)
> superthis.d(12): Error: semicolon expected to close alias declaration
> superthis.d(12): Error: found 'this' when expecting '('
> superthis.d(12): Error: basic type expected, not ;
> superthis.d(12): Error: found ';' when expecting ')'
> superthis.d(17): Error: semicolon expected following function declaration
> Compilation failed.
>
> uncommenting line 13:
> superthis.d(13): Error: this is not a type
>
> I've got a mixin to work though:
>
> class EFoo : Exception
> {
> 	mixin SuperCtors;
> }
>
> mixin template SuperCtors()
> {
> 	this(T...)(T args)
> 	if (__traits(compiles, {new typeof(super)(args);}))
> 	{super(args);}
> }
>
> But it would be nicer if an alias statement could work to avoid defining the mixin in every project that needs it.
>
> Partly I'm interested in this as I'm wondering if 'alias this' conflicts with 'normal' alias syntax when aliasing constructors.

The problem is that Exception class ctor requires at least one explicit argument (https://github.com/D-Programming-Language/druntime/blob/master/src/object.di#L339).

To solve the problem in general case you can either supply default arguments for all ctor parameters or define parameter-less ctor.

In your particular case because you cannot change Exception you can inherit not from Exception class but from intermediate one, which does one of the mentioned things:

import std.stdio;

class DException : Exception
{
	this(string value = "") { super(value); }
}

class A : DException
{

}

void main()
{
	A a = new A;
}
December 26, 2012
On 26/12/2012 15:13, Maxim Fomin wrote:
> The problem is that Exception class ctor requires at least one explicit
> argument
> (https://github.com/D-Programming-Language/druntime/blob/master/src/object.di#L339).
>
>
> To solve the problem in general case you can either supply default
> arguments for all ctor parameters or define parameter-less ctor.
>
> In your particular case because you cannot change Exception you can
> inherit not from Exception class but from intermediate one, which does
> one of the mentioned things:
>
> import std.stdio;
>
> class DException : Exception
> {
>      this(string value = "") { super(value); }
> }

Thanks for the reply. But actually I'm not looking to define a parameter-less ctor for Exception subclasses, but to copy all of a parent class's constructors into a subclass. This is nice to do for Exception subclasses because sometimes I just want a new type that behaves exactly the same, but has different RTTI. But for other classes it can be useful if you want to override some methods, but don't need to add/change any constructors, apart from exposing them from the parent.

I've found a relevant discussion:
http://forum.dlang.org/post/op.u36pc3y4o7cclz@korden-pc
December 26, 2012
On Wednesday, 26 December 2012 at 17:11:31 UTC, Nick Treleaven wrote:
> On 26/12/2012 15:13, Maxim Fomin wrote:
>> The problem is that Exception class ctor requires at least one explicit
>> argument
>> (https://github.com/D-Programming-Language/druntime/blob/master/src/object.di#L339).
>>
>>
>> To solve the problem in general case you can either supply default
>> arguments for all ctor parameters or define parameter-less ctor.
>>
>> In your particular case because you cannot change Exception you can
>> inherit not from Exception class but from intermediate one, which does
>> one of the mentioned things:
>>
>> import std.stdio;
>>
>> class DException : Exception
>> {
>>     this(string value = "") { super(value); }
>> }
>
> Thanks for the reply. But actually I'm not looking to define a parameter-less ctor for Exception subclasses, but to copy all of a parent class's constructors into a subclass. This is nice to do for Exception subclasses because sometimes I just want a new type that behaves exactly the same, but has different RTTI. But for other classes it can be useful if you want to override some methods, but don't need to add/change any constructors, apart from exposing them from the parent.
>
> I've found a relevant discussion:
> http://forum.dlang.org/post/op.u36pc3y4o7cclz@korden-pc

Currently dmd always creates implicit constructor for derived classes if base class has a ctor. This can be prevented by annotating ctor as a @disable, but it is unacceptable because you have to write another constructor. So, there is no way for not creating implicit constructor in a convenient way.