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