Limited member function templates?

Daniel Keep daniel.keep.lists at gmail.com
Sat Nov 10 06:37:07 PST 2007



Christopher Wright wrote:
> Janice Caron wrote:
>> On 11/10/07, Janice Caron <caron800 at googlemail.com> wrote:
>>> On 11/10/07, Bill Baxter <dnewsgroup at billbaxter.com> wrote:
>>>>   The only thing you can't have is _virtual_ member function templates.
>>>>   Is making them virtual what you are talking about?
>>> All member functions in D are virtual (unless you explicitly use the
>>> "final" keyword). So obviously, yes.
>>
>> When we get the common calling convention whereby f(x) and x.f() are
>> interchangable, then adding non-polymorphic template functions will be
>> a piece of cake.
>>
>> Just declare as f(T)(X x, T t) { ... } and call as x.f(t).
>>
>> Maybe that will be enough. But yeah - I intended to mean "normal"
>> functions. Polymorphic. Virtual.
> 
> I was just about to feature-request virtual templated member functions.
> I can't mock them, which is one of two major problems in my mocks
> library. You also can't have a templated method in an interface:
> 
> interface Collection (T) {
>    void addAll(U : T) (Collection!(U) toAdd); // fail
> }
> 
> Which leads to annoyances: "why can't I add all my Bicycles to my
> Vehicles collection?"

Think about what you're asking for.  An interface defines, essentially,
a block of vtable addresses and what they mean.  So, in a loose sense,

interface Foo { void bar(); void baz(); }

Says that for any class that implements Foo, there need to be a block of
two vtable entries that point to the implementations of bar and baz.

Let's try a different interface:

interface Quxx { void zyzzy(T)(T); }

How many vtable entries is that?

There is no sane answer, because it depends on how the interface is
used.  And not just in one place: any module in the program could alter
the number, order and meaning of the vtable block.  If this got
introduced, single-file compilation would be impossible: you'd need to
parse the *entire* program first, and *then* work on generating output.

You might say "well, just treat templated methods differently!"  The
problem then is how exactly *do* you implement them?  In order for an
interface to work, you need to be able to cast down to it from any
implementation.  This means the "template" has to be expressible as a
run-time pointer or something.  But templates are inherently
compile-time beasts.  Maybe you could return an array of pointers for
each instantiation in the implementation, but you still wouldn't be able
to guarantee whether a particular instantiation exists or not.

If you're going to go down that road, you might as well just give up and
go straight for dynamic dispatch, or just pass around Variants.  It'll
end up about the same.

Trust me, there have been a few times I would have *killed* for
templates in interfaces.  I actually went and wrote my Variant type
specifically because I couldn't.  :P  That said, I don't think this is a
restriction that's going to be lifted any time soon.

Standard disclaimer: I can always be wrong.  Also, it's 1:36 AM right
now, which increases those chances. :P

	-- Daniel



More information about the Digitalmars-d mailing list