template member function confusion

Jonathan M Davis jmdavisProg at gmx.com
Sun Apr 8 14:18:41 PDT 2012


On Sunday, April 08, 2012 22:51:51 Francois Chabot wrote:
> Hello, I've been getting into the language recently, and ror the
> most part, it's going pretty smoothly.
> 
> I have finally run into the first major snag that's really making
> me scratch my head. Mind you, I can easily code around it, but
> I'd like to understand why it's not working:
> 
> 
> Given (roughly) the following code:
> class Binding
> {
>    ...
> }
> 
> class Bar
> {
>    Binding[string] Bindings ;
> 
>    //cached function
>    void foo( Foo target , const ref Matrix44 val ) { ... }
>    void foo( Foo target , const ref Vec4 val ) { ... }
>    //... more function...
> 
>    //convenience interface for non-critical code-paths
>    void foo(T)( string target , const ref T val ) { foo(
> Bindings[target] , val ) ; }
> 
> }
> 
> DMD gives me the following:
> Error: Bar.foo(T) conflicts with function Bar.foo at ...
> 
> Now, I can easily
> A) Change the name of either one the functions (which yields a
> slightly less elegant interface)
> B) Not use a template and put string versions of all the foos
> (which yields ugly code)
> C) Make the binding-based interface a template and implement the
> functions through specialization (as they are unfortunately
> different enough to not be templatable). While maintaining the
> interface and conciseness, it feels like a hack to me.
> 
> I just can't wrap my head around why my current implementation
> cannot work. Any insight?

Two issues here.

1. You cannot currently overload a templated function with a non-templated 
function or vice versa: http://d.puremagic.com/issues/show_bug.cgi?id=1528 
This is a bug which should work and should work at some point. The workaround 
is to templatize the non-templated functions with empty parens. e.g.

void foo()(Foo target, const ref Matrix44 val)

2. Template functions are non-virtual and will _never_ be virtual. This 
probably isn't causing you any compilation issues, but it does mean that you 
must be careful with using templated functions in classes. It means that 
templatizing all of the foos will mean that none of them are virtual (though 
that's arguably better than making some of them virtual and some not, since 
that has its own set of issues). Regardless, if you have an API which relies 
on having a templated function be virtual, you're going to have to find a way 
to work around it, because templated functions _can't_ be virtual.

- Jonathan M Davis


More information about the Digitalmars-d-learn mailing list