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));

Reply via email to