On Sunday, 8 April 2012 at 20:51:52 UTC, Francois Chabot wrote:
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.

If you ask me, choose C - that's the most consistent solution. It's perfectly OK to have specialized templates. That's not a hack, it's a feature ;-)

Regarding the virtualization discussion: You could still use method dispatcher pairs, such as

// Specialization
void foo(T: Matrix44)( Foo target , const ref Matrix44 val ) { myfoo(target , val); } void myfoo( Foo target , const ref Matrix44 val ) { /* real functionality here */ }
// general "swiss knife"
void foo(T)( string target , const ref T val ) { myfoo(target , val); } void myfoo( Foo target , const ref Variant val ) { /* real functionality here */ }

Then the myfoo methods would be overloadable. If you want the "total hack", you could wrap the specialization pairs into mixins. This way, only the foo wrappers are visible to the human user, but the compiler also sees the overloadable, "ordinary" methods.

Cheers,
Stefan

Reply via email to