Using templates with interfaces

via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sun Jun 25 10:19:33 PDT 2017


On Sunday, 25 June 2017 at 13:32:57 UTC, Andrew Chapman wrote:
> I think you've answered the question with "You cannot have 
> unimplemented templates in interfaces".  Thanks for the answer.
>  I'll rethink the way I'm doing this.
>
> Cheers.

Yes, function templates in classes or interfaces are implicitly 
marked as final - meaning that you have to provide an 
implementation. However that is still useful. For example in one 
my projects I wanted to support configuration files written in 
either JSON or SDLang, however since std.json and sdlang-d had 
(as expected) different APIs, I decided to wrap them in classes 
implementing a common interface, so I could solve this in one 
place and be done with it. SDLang and JSON have a tree like 
structure and a common task is that I needed to interpret the 
value at a particular node as a scalar. Here's how I had done it:

interface Node
{
     final T get(T)() const
     {
         static if (isBoolean!T) return getBool();
         else static if (isIntegral!T) return to!T(getInt());
         else static if (isFloatingPoint!T) return 
to!T(getFloat());
         else static if (isSomeString!T) return to!T(getString());
         else static assert(0, "Type not supported: " ~ 
T.stringof);
     }

     const(Node) getChild(string name) const;

     protected:
     bool getBool() const;
     long getInt() const;
     double getFloat() const;
     string getString() const;
}

That way I could write a generic deserializer that iterates over 
the fields of the object and called the get method like this:

foreach (idx, member; obj.tupleof)
     obj.tupleof[idx] =
         node.getChild(
                 typeof(obj).tupleof[idx].stringof)
             .get!(typeof(member));


More information about the Digitalmars-d-learn mailing list