Thread overview
"this" as default parameter for a constructor.
Apr 11, 2021
Pierre
Apr 12, 2021
Kagamin
Apr 13, 2021
Pierre
Apr 12, 2021
Jack
Apr 14, 2021
Mathias LANG
April 11, 2021
Hi,

I have a class with a reference to the parent object and a constructor that has the parent as parameter

class foo {
	this ( foo p /* , other params */ ) {
		parent = p;
	}

	foo parent;
}

Of cause, the parent is almost always the object that creates the new intance. So

auto f = new foo(this);

I'd like to set "this" ( the creator ) as default argument if the constructor :

this ( foo p = this ) {...}

I can't. But however, the function, the argument and the current object in body of the constructor are 3 different things and the compiler can distinguish each one.

Is there a way to pass the reference of the caller to the creator as default argument ?

April 12, 2021
class foo {
	this ( foo p /* , other params */ ) {
		parent = p;
	}
	foo create() {
		return new foo(this);
	}
	void use() {
		foo f = create();
	}

	foo parent;
}
April 12, 2021
On Sunday, 11 April 2021 at 20:38:10 UTC, Pierre wrote:
> Hi,
>
> I have a class with a reference to the parent object and a constructor that has the parent as parameter
>
> class foo {
> 	this ( foo p /* , other params */ ) {
> 		parent = p;
> 	}
>
> 	foo parent;
> }
>
> Of cause, the parent is almost always the object that creates the new intance. So
>
> auto f = new foo(this);
>
> I'd like to set "this" ( the creator ) as default argument if the constructor :
>
> this ( foo p = this ) {...}
>
> I can't. But however, the function, the argument and the current object in body of the constructor are 3 different things and the compiler can distinguish each one.
>
> Is there a way to pass the reference of the caller to the creator as default argument ?

it isn't supported as far i know so use a default construtor like @Kagamin has show
April 13, 2021
On Monday, 12 April 2021 at 13:14:27 UTC, Kagamin wrote:
> class foo {
> 	this ( foo p /* , other params */ ) {
> 		parent = p;
> 	}
> 	foo create() {
> 		return new foo(this);
> 	}
> 	void use() {
> 		foo f = create();
> 	}
>
> 	foo parent;
> }

It's a solution. But my foo class is a base for several subclasses which each have their own constructor with different parameters; i should define as much create function as subclasses constructors. that's unelegant. I tried do solve it with templates but couldn't found a satisfatory solution.

As @Jack say " this ( T p = this ){...} " if not supported, not yet, maybe it should be ?

By now, the "best" way i found is to write auto f = new foo(this);
April 14, 2021

On Sunday, 11 April 2021 at 20:38:10 UTC, Pierre wrote:

>

Hi,

I have a class with a reference to the parent object and a constructor that has the parent as parameter

class foo {
this ( foo p /* , other params */ ) {
parent = p;
}

foo parent;
}

Of cause, the parent is almost always the object that creates the new intance. So

auto f = new foo(this);

I'd like to set "this" ( the creator ) as default argument if the constructor :

this ( foo p = this ) {...}

I can't. But however, the function, the argument and the current object in body of the constructor are 3 different things and the compiler can distinguish each one.

Is there a way to pass the reference of the caller to the creator as default argument ?

Depending on what you are trying to do, I would recommend to instead go with nested classes if you can. E.g.

class MyClass {
    class MyChild {
        this (int value) { this.value = value; }
        private int value;
    }
}

void main ()
{
    auto mc = new MyClass;
    auto child = mc.new MyChild(42);
}

It'll give you an automatic reference to the parent. Of course if you are trying to do something like linked list, where all elements have the same type, it won't work.
In this case, the create approach might be better. You should be able to cook something with a template this parameter to reduce boilerplate.

And regarding allowing this as default argument: Definitely no. While it could be possible with some stretch (e.g. we'll have to delay default parameter semantic to the call site, unlike what is currently done, and that would mess with things like overload resolutions and template type inference), it wouldn't be sound / it'd be very surprising. I for one would expect this to be the object referencing itself, not the this of my caller.