User defined types: Problems with ref

Chris wendlec at tcd.ie
Fri Jan 24 06:45:03 PST 2014


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.


More information about the Digitalmars-d-learn mailing list