Thread overview
Pass 'this' as reference
Sep 12, 2018
Jan
Sep 12, 2018
Adam D. Ruppe
Sep 13, 2018
Jan
Sep 13, 2018
Jonathan M Davis
Sep 15, 2018
Jan
Sep 15, 2018
Jonathan M Davis
Sep 19, 2018
Jan
September 12, 2018
I'm using D not for that long and lately I have encountered an issue. I have class 'Foo' with a constructor using this signature:
`this (ref Bar original)`

In the 'Bar' class itself I want to create an instance of 'Foo' using 'this' as parameter. Something in the way of:
`Foo foo = new Foo(ref this);`

I couldn't find anything interesting on the internet to help me. Could anyone help me? Many thanks in advance!
September 12, 2018
On Wednesday, 12 September 2018 at 15:01:36 UTC, Jan wrote:
> I'm using D not for that long and lately I have encountered an issue. I have class 'Foo' with a constructor using this signature:
> `this (ref Bar original)`

classes and the ref keyword should very rarely be used together in D. classes are already refs without anything, so adding it makes it a double ref, which breaks more than it helps.

If you just get rid of the `ref`s in your code it will probably work.
September 12, 2018
On 9/12/18 8:01 AM, Jan wrote:
> I'm using D not for that long and lately I have encountered an issue. I have class 'Foo' with a constructor using this signature:
> `this (ref Bar original)`
> 
> In the 'Bar' class itself I want to create an instance of 'Foo' using 'this' as parameter. Something in the way of:
> `Foo foo = new Foo(ref this);`
> 
> I couldn't find anything interesting on the internet to help me. Could anyone help me? Many thanks in advance!

You don't have to specify ref when calling. This should work:

auto foo = new Foo(this);

Though almost certainly you are misunderstanding classes -- they are references anyway. I don't know why you would want to accept a class via ref unless you were actually going to reassign the reference. I suggest that your constructor should not accept Bar via ref.

-Steve
September 13, 2018
Many thanks Adam and Steve! Works like a charm! :D
I presumed classes are lvalues. I shouldn't make things more complicated than they are ;-)
September 13, 2018
On Thursday, September 13, 2018 4:04:58 AM MDT Jan via Digitalmars-d-learn wrote:
> Many thanks Adam and Steve! Works like a charm! :D
> I presumed classes are lvalues. I shouldn't make things more
> complicated than they are ;-)

Well, the variables _are_ lvalues. It's just that they're references to objects rather than the objects themselves. You never refer to a class object directly in D. Rather, you're always dealing with a reference to a class object. Class references are basically pointers except that you can't dereference them directly, just call member functions on them (which in D means implicitly dereferencing whether you're talking about pointers or class references). In that respect, they're like classes in Java. So, if you assign a value to a class reference, you're assigning the reference, not the class object itself, just like when you assign a value to a pointer, you're mutating the pointer itself, not mutating the object that it points to.

- Jonathan M Davis



September 15, 2018
On Thursday, 13 September 2018 at 11:08:30 UTC, Jonathan M Davis wrote:
> [...]

Thanks for clarifying Jonathan :)
But aren't the variables considered rvalues then?
September 15, 2018
On Saturday, September 15, 2018 11:44:05 AM MDT Jan via Digitalmars-d-learn wrote:
> On Thursday, 13 September 2018 at 11:08:30 UTC, Jonathan M Davis
>
> wrote:
> > [...]
>
> Thanks for clarifying Jonathan :)
> But aren't the variables considered rvalues then?

No. variables are _always_ lvalues. An lvalue is an object which is addressable and which can therefore be assigned a value (ignoring issues of constness). The name comes from the fact that lvalues are allowed on the left-hand side of an assignment operation, whereas rvalues are only allowed on the right. e.g.

int i;
int* p;

are both lvalues. They have addresses and can be assigned to.

i = 42;
p = &i;
auto p2 = &p;

On the other hand, the return value of

int foo(string s);

is an rvalue. How it's actually stored is compiler-defined; you can't take its address, and you can't assign to it.

foo("bar") = 42; // illegal
auto p = &foo("bar"); // illegal

On the other hand,

ref int foo(string s);

returns by ref, so it's returning an lvalue. Its address can be taken, and it can be assigned a value.

foo("bar") = 42; // legal
auto p = &foo("bar"); // legal

Because a pointer or reference points to a specific address, even if the pointer itself is an rvalue, what it points to is almost always an lvalue, (the main case where it isn't an lvalue would be something like a function pointer, since you can take a function's address, but you can't assign to it). So, something like

int* foo(string s);
*foo("bar") = 42;

compiles. However, ultimately, you can't know whether a particular value is an lvalue or rvalue without context. A variable is always an lvalue, whereas a return value usually isn't - but it can be if it's returned by ref. And a variable and return value could both be the same type - int, int*, string, etc. So, the type itself doesn't tell you whether something is an lvalue or rvalue. It's how it's stored that tells you.

Ultimately though, if you want to know whether something is an lvalue or rvalue, consider whether it's something that can go on the left-hand side of an assignment operation (ignoring its constness), or whether it can only go on the right-hand side.

https://msdn.microsoft.com/en-us/library/f90831hc.aspx https://stackoverflow.com/questions/17357888/exact-difference-between-rvalue-and-lvalue https://www.quora.com/What-is-lvalue-and-rvalue-in-C

- Jonathan M Davis



September 19, 2018
On Saturday, 15 September 2018 at 20:13:51 UTC, Jonathan M Davis wrote:
> On Saturday, September 15, 2018 11:44:05 AM MDT Jan via Digitalmars-d-learn wrote:
>> [...]
>
> No. variables are _always_ lvalues. An lvalue is an object which is addressable and which can therefore be assigned a value (ignoring issues of constness). The name comes from the fact that lvalues are allowed on the left-hand side of an assignment operation, whereas rvalues are only allowed on the right. e.g.
>
> [...]

Many thanks Jonathan! :)