Calls to struct methods and immutable

Joseph Rushton Wakeling joseph.wakeling at webdrake.net
Tue Nov 27 04:16:08 PST 2012


On 11/16/2012 05:51 AM, Ali Çehreli wrote:
> If makeFoo() were not pure, and in general, Foo may need to provide an .idup
> member function:

I've been trying this out and ran into some problems with the to!()() conversion.

Here's a concrete example.  Suppose I have a couple of structs which are 
designed respectively to represent nodes in a network, and a collection of those 
nodes:

///////////////////////////////////////////////////////////////////////
alias Tuple!(uint, "id") Link;

struct Node
{
       uint id;
       Link[] links;

       void addLink(uint l)
       {
             links ~= Link(l);
       }

       immutable(Node) idup() pure const @property
       {
             auto linkCopy = to!(Link[])(links);
             immutable ilinks = assumeUnique(linkCopy);
             return immutable(Node)(id, ilinks);
       }
}


struct Network
{
       Node[uint] nodes;

       void add(uint i, uint j)
       {
             if((i in nodes) is null)
                   nodes[i] = Node(i);
             if((j in nodes) is null)
                   nodes[j] = Node(j);

             nodes[i].addLink(j);
             nodes[j].addLink(i);
       }

       void print()
       {
             foreach(k; nodes.keys)
             {
                   write("[", k, "]");
                   foreach(l; nodes[k].links)
                         write(" ", l.id);
                   writeln();
             }
             writeln();
       }
}
///////////////////////////////////////////////////////////////////////

Now, the idup() command for Node works just fine:

       auto n1 = Node(1);

       n1.addLink(5);
       n1.addLink(6);
       writeln(n1.links);

       immutable n2 = n1.idup;
       writeln(n2.links);

...  but if I try to introduce a similar function for the Network struct,

       immutable(Network) idup() pure const @property
       {
             auto nodeCopy = to!(Node[uint])(nodes);
             immutable imnodes = assumeUnique(nodeCopy);
             return immutable(Network)(imnodes);
       }

it fails to compile with an error relating to the to!(Node[uint])() conversion:

---------------------------------------------------------------------------------
/opt/dmd/include/d2/std/conv.d(269): Error: template std.conv.toImpl does not 
match any function template declaration. Candidates are:
/opt/dmd/include/d2/std/conv.d(325):        std.conv.toImpl(T, S)(S value) if 
(isImplicitlyConvertible!(S, T) && !isEnumStrToStr!(S, T) && !isNullToStr!(S, T))
/opt/dmd/include/d2/std/conv.d(431):        std.conv.toImpl(T, S)(ref S s) if 
(isRawStaticArray!(S))
/opt/dmd/include/d2/std/conv.d(445):        std.conv.toImpl(T, S)(S value) if 
(is(S : Object) && !is(T : Object) && !isSomeString!(T) && hasMember!(S, "to") 
&& is(typeof(S.init.to!(T)()) : T))
/opt/dmd/include/d2/std/conv.d(466):        std.conv.toImpl(T, S)(S value) if 
(is(typeof(S.init.opCast!(T)()) : T) && !(isSomeString!(T) && !is(T == enum) && 
!isAggregateType!(T)))
/opt/dmd/include/d2/std/conv.d(497):        std.conv.toImpl(T, S)(S value) if 
(!isImplicitlyConvertible!(S, T) && is(T == struct) && is(typeof(T(value))))
/opt/dmd/include/d2/std/conv.d(269):        ... (16 more, -v to show) ...
/opt/dmd/include/d2/std/conv.d(325): Error: template std.conv.toImpl cannot 
deduce template function from argument types !(Node)(const(Node))
/opt/dmd/include/d2/std/conv.d(269): Error: template instance toImpl!(Node) 
errors instantiating template
/opt/dmd/include/d2/std/conv.d(1387): Error: template instance 
std.conv.to!(Node).to!(const(Node)) error instantiating
/opt/dmd/include/d2/std/conv.d(269):        instantiated from here: 
toImpl!(Node[uint], const(Node[uint]))
inodes.d(41):        instantiated from here: to!(const(Node[uint]))
/opt/dmd/include/d2/std/conv.d(269): Error: template instance 
std.conv.toImpl!(Node[uint], const(Node[uint])) error instantiating
inodes.d(41):        instantiated from here: to!(const(Node[uint]))
inodes.d(41): Error: template instance 
std.conv.to!(Node[uint]).to!(const(Node[uint])) error instantiating
---------------------------------------------------------------------------------

I'm guessing this means I have to define a custom opCast (for Node, I guess) but 
the documentation on how to do so seems sparse -- can you advise?

Full code example attached.

Thanks & best wishes,

      -- Joe
-------------- next part --------------
A non-text attachment was scrubbed...
Name: inodes.d
Type: text/x-dsrc
Size: 1146 bytes
Desc: not available
URL: <http://lists.puremagic.com/pipermail/digitalmars-d-learn/attachments/20121127/516a123f/attachment.d>


More information about the Digitalmars-d-learn mailing list