How does one use toString() inside of the class's hash function? Compiler error

Salih Dincer salihdb at hotmail.com
Wed Apr 2 20:43:43 UTC 2025


On Tuesday, 1 April 2025 at 09:21:25 UTC, Daniel Donnelly, Jr. 
wrote:


> Error: @safe function def.Def.toHash cannot call @system 
> function def.Def.toString: def.Def.toString is declared here...
> ```
> I've always wondered about this, because I run into it every 
> time I have an idea and begin to code.  It's a major bottleneck 
> to my coding performance.
>
> How can we fix it?

The function (toHash) does not return any values. Maybe it's the 
reason for the error, but let me share code for inspiration. 
Maybe it's not simple, but I use this way:

```d
class C(T)
{
   size_t id;
   private T latex;

   invariant {
     static assert(!__traits(isFloating, T));
   }

   this() {
     if (latex == latex.init) id = size_t.max;
     else id = typeid(latex).getHash(&latex);
   }

   this(T value) {
     latex = value;
     this();
   }

   size_t length() => toString.length;//*
   string opUnary(string op)() const
   if (op == "*") {
     import std.string : format;
     return format("@%s", &latex);
   }//*/
   
   override const @safe nothrow
   {
     string toString()
     {
       import std.conv : to;
       return latex.to!string;
     }

     size_t toHash()
     {
       static if (is(T == string))
       {
         auto i = toString;
         return i.hashOf;
       } else return id;
     }

     bool opEquals(Object rhs)
     {
       return rhs.toHash == this.toHash; /*
       return rhs is this;//*/
     }
   }
}

unittest
{
   auto cHelper(T)(T value) => new C!T(value);

   auto a = cHelper("foo");
   auto b = cHelper("zoo");

   assert(a != b, "equalised!");
   assert(*a != *b);

   // but ->
   assert(a.id == a.toHash); // or
   assert(b.id == b.toHash);

   imported!"std.stdio".writeln(*a);
   // "@7F......"
}

SDB at 79


More information about the Digitalmars-d-learn mailing list