Thread overview |
---|
January 23, 2014 User defined types: Problems with ref | ||||
---|---|---|---|---|
| ||||
Here's what I'm trying to do. struct Element(T) { T x; T y; public void setX(T value) { x = value; } // More fancy functions ... } I store Element(s) in an array and want to pass each one by reference, which does not work. class Tree { Element!string[] elements; public ref auto createElement(string name) { elements ~= Element!string(name); return elements[$-1]; } } in main: auto tag = Element!string("first"); The elements in Tree.elements and the ones in main are not the same, instead I obtain a copy of each. How can I make them refer to the same Elements? If I have to add a .ptr property to Element, how do I do that? Is that possible at all or did I shoot myself in the foot with the template? |
January 23, 2014 Re: User defined types: Problems with ref | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chris | On Thursday, 23 January 2014 at 15:24:19 UTC, Chris wrote:
> Here's what I'm trying to do.
>
> struct Element(T) {
> T x;
> T y;
>
> public void setX(T value) {
> x = value;
> }
> // More fancy functions ...
> }
>
> I store Element(s) in an array and want to pass each one by reference, which does not work.
>
>
> class Tree {
>
> Element!string[] elements;
>
> public ref auto createElement(string name) {
> elements ~= Element!string(name);
> return elements[$-1];
> }
> }
>
> in main:
>
> auto tag = Element!string("first");
>
> The elements in Tree.elements and the ones in main are not the same, instead I obtain a copy of each.
> How can I make them refer to the same Elements? If I have to add a .ptr property to Element, how do I do that? Is that possible at all or did I shoot myself in the foot with the template?
Sorry in main it is:
auto tree = new Tree();
auto tag = tree.createElement("first");
|
January 23, 2014 Re: User defined types: Problems with ref | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chris | On Thursday, 23 January 2014 at 15:24:19 UTC, Chris wrote:
> Here's what I'm trying to do.
>
> struct Element(T) {
> T x;
> T y;
>
> public void setX(T value) {
> x = value;
> }
> // More fancy functions ...
> }
>
> I store Element(s) in an array and want to pass each one by reference, which does not work.
>
>
> class Tree {
>
> Element!string[] elements;
>
> public ref auto createElement(string name) {
> elements ~= Element!string(name);
> return elements[$-1];
> }
> }
>
> in main:
>
> auto tag = Element!string("first");
>
> The elements in Tree.elements and the ones in main are not the same, instead I obtain a copy of each.
> How can I make them refer to the same Elements? If I have to add a .ptr property to Element, how do I do that? Is that possible at all or did I shoot myself in the foot with the template?
You can use pointer
Tree tree = new Tree();
Element!(string)* element = &tree.createElement("first");
& is to get address of returned value element.
You also can rewrite your function like this:
public Element!(string)* createElement(string name) {
elements ~= Element!string(name);
return &elements[$-1];
}
to return pointer without need to get address on caller side.
|
January 23, 2014 Re: User defined types: Problems with ref | ||||
---|---|---|---|---|
| ||||
Posted in reply to FreeSlave | On Thursday, 23 January 2014 at 15:34:38 UTC, FreeSlave wrote:
> On Thursday, 23 January 2014 at 15:24:19 UTC, Chris wrote:
>> Here's what I'm trying to do.
>>
>> struct Element(T) {
>> T x;
>> T y;
>>
>> public void setX(T value) {
>> x = value;
>> }
>> // More fancy functions ...
>> }
>>
>> I store Element(s) in an array and want to pass each one by reference, which does not work.
>>
>>
>> class Tree {
>>
>> Element!string[] elements;
>>
>> public ref auto createElement(string name) {
>> elements ~= Element!string(name);
>> return elements[$-1];
>> }
>> }
>>
>> in main:
>>
>> auto tag = Element!string("first");
>>
>> The elements in Tree.elements and the ones in main are not the same, instead I obtain a copy of each.
>> How can I make them refer to the same Elements? If I have to add a .ptr property to Element, how do I do that? Is that possible at all or did I shoot myself in the foot with the template?
>
> You can use pointer
>
> Tree tree = new Tree();
> Element!(string)* element = &tree.createElement("first");
>
> & is to get address of returned value element.
>
> You also can rewrite your function like this:
>
> public Element!(string)* createElement(string name) {
> elements ~= Element!string(name);
> return &elements[$-1];
> }
>
> to return pointer without need to get address on caller side.
Thanks, that was fast! Yes I was tinkering around with pointers, but didn't get it right, you did. However, the output is still the same, i.e. two different sets:
// After creating and changing
<div id="1">
Hello, world!
<span>
</span>
</div>
// The Elements in Tree.elements:
[<div>
</div>
, <span>
</span>
]
|
January 24, 2014 Re: User defined types: Problems with ref | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chris |
On Thursday, 23 January 2014 at 15:24:19 UTC, Chris wrote:
> Thanks, that was fast! Yes I was tinkering around with pointers, but didn't get it right, you did. However, the output is still the same, i.e. two different sets:
>
> // After creating and changing
> <div id="1">
> Hello, world!
> <span>
> </span>
> </div>
>
> // The Elements in Tree.elements:
> [<div>
> </div>
> , <span>
> </span>
> ]
Maybe more code will explain more.
Note that array requires data to be continuous, so if there are no space for new element, it reallocates the whole chunk and therefore invalidates old pointers. Use linked list or replace struct with class.
|
January 24, 2014 Re: User defined types: Problems with ref | ||||
---|---|---|---|---|
| ||||
Posted in reply to FreeSlave | Anyway, why do you need pointers to elements? |
January 24, 2014 Re: User defined types: Problems with ref | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chris | On 01/23/2014 07:26 AM, Chris wrote: > On Thursday, 23 January 2014 at 15:24:19 UTC, Chris wrote: >> Here's what I'm trying to do. >> >> struct Element(T) { >> T x; >> T y; >> >> public void setX(T value) { >> x = value; >> } >> // More fancy functions ... >> } >> >> I store Element(s) in an array and want to pass each one by reference, >> which does not work. >> >> >> class Tree { >> >> Element!string[] elements; >> >> public ref auto createElement(string name) { >> elements ~= Element!string(name); >> return elements[$-1]; >> } >> } >> >> in main: >> >> auto tag = Element!string("first"); >> >> The elements in Tree.elements and the ones in main are not the same, >> instead I obtain a copy of each. >> How can I make them refer to the same Elements? If I have to add a >> .ptr property to Element, how do I do that? Is that possible at all or >> did I shoot myself in the foot with the template? > > Sorry in main it is: > > auto tree = new Tree(); > auto tag = tree.createElement("first"); createElement does return a reference. However, because D does not have local references the type of tag is Element!string (not 'ref Element!string'). The following program demonstrates that the address of the returned reference is indeed the same as the one that has been created: import std.stdio; struct Element(T) { T x; T y; public void setX(T value) { x = value; } // More fancy functions ... } class Tree { Element!string[] elements; public ref auto createElement(string name) { elements ~= Element!string(name); writefln(" created element at %s", &elements[$-1]); return elements[$-1]; } } void main() { auto tree = new Tree(); writefln("received element at %s", &tree.createElement("first")); } Sample output: created element at 7F14C72C0F80 received element at 7F14C72C0F80 You can use the returned element directly as well: tree.createElement("second").setX("hello"); Ali |
January 24, 2014 Re: User defined types: Problems with ref | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On Friday, 24 January 2014 at 01:26:06 UTC, Ali Çehreli wrote:
> On 01/23/2014 07:26 AM, Chris wrote:
>
> > On Thursday, 23 January 2014 at 15:24:19 UTC, Chris wrote:
> >> Here's what I'm trying to do.
> >>
> >> struct Element(T) {
> >> T x;
> >> T y;
> >>
> >> public void setX(T value) {
> >> x = value;
> >> }
> >> // More fancy functions ...
> >> }
> >>
> >> I store Element(s) in an array and want to pass each one by
> reference,
> >> which does not work.
> >>
> >>
> >> class Tree {
> >>
> >> Element!string[] elements;
> >>
> >> public ref auto createElement(string name) {
> >> elements ~= Element!string(name);
> >> return elements[$-1];
> >> }
> >> }
> >>
> >> in main:
> >>
> >> auto tag = Element!string("first");
> >>
> >> The elements in Tree.elements and the ones in main are not
> the same,
> >> instead I obtain a copy of each.
> >> How can I make them refer to the same Elements? If I have to
> add a
> >> .ptr property to Element, how do I do that? Is that possible
> at all or
> >> did I shoot myself in the foot with the template?
> >
> > Sorry in main it is:
> >
> > auto tree = new Tree();
> > auto tag = tree.createElement("first");
>
> createElement does return a reference. However, because D does not have local references the type of tag is Element!string (not 'ref Element!string').
>
> The following program demonstrates that the address of the returned reference is indeed the same as the one that has been created:
>
> import std.stdio;
>
> struct Element(T) {
> T x;
> T y;
>
> public void setX(T value) {
> x = value;
> }
> // More fancy functions ...
> }
>
> class Tree {
>
> Element!string[] elements;
>
> public ref auto createElement(string name) {
> elements ~= Element!string(name);
> writefln(" created element at %s", &elements[$-1]);
> return elements[$-1];
> }
> }
>
> void main()
> {
> auto tree = new Tree();
> writefln("received element at %s", &tree.createElement("first"));
> }
>
> Sample output:
>
> created element at 7F14C72C0F80
> received element at 7F14C72C0F80
>
> You can use the returned element directly as well:
>
> tree.createElement("second").setX("hello");
>
> Ali
Thank you guys. Yes, it's the array bit that kills the reference as FreeSlave pointed out. After tinkering around with it, I've (reluctantly) turned Element into a class to get the reference semantics. I need a reference so I can do things like
tree.getElementById("div");
It's a basic (very simple) HTML / markup thing. Tree stores all elements, but the elements are changed outside Tree, like so
auto div = tree.createElement("div");
div.setAttribute("id", "1");
// ...
div.appendChild(...);
etc.
I'm sure there are cleverer ways of implementing a HTML tree.
|
January 24, 2014 Re: User defined types: Problems with ref | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chris | Now the output is as it should be (after changing the elements). // The div.toString(); <div class="text" onclick="function();" id="1"> Hello, world! <span> I am a span </span> </div> // Tree Elements [<div class="text" onclick="function();" id="1"> Hello, world! <span> I am a span </span> </div> , <span> I am a span </span> ] |
Copyright © 1999-2021 by the D Language Foundation