October 08, 2017
Following a request from a couple of users to make it possible to use open methods and templates together, I toyed with a couple of ideas, until I discovered that the current implementation supports method and override templates already...well, almost, because there is a need to navigate around a couple of bugs (or limitations) in the various D compilers.

I have an example in a branch (https://github.com/jll63/openmethods.d/tree/method-template-example) that adds a new mixin for manually registering classes - to be used for class template instantiations, which do not appear on ModuleInfo.localClasses. Apart from that the existing machinery is up to the task - although it requires some help from the user. Here is the gist of it (complete example here: https://github.com/jll63/openmethods.d/blob/method-template-example/tests/methodtemplates.d):

  class Matrix(T) {}
  class DenseMatrix(T) : Matrix!(T) {}
  class DiagonalMatrix(T) : Matrix!(T) {}

  template declareMatrixMethods(T)
  {
    mixin registerClasses!(Matrix!T);
    mixin registerClasses!(DenseMatrix!T);
    mixin registerClasses!(DiagonalMatrix!T);

    Matrix!T times(virtual!(Matrix!T), T);
    Matrix!T times(T, virtual!(Matrix!T));
  }

  mixin(registerMethods("declareMatrixMethods!double"));
  mixin(registerMethods("declareMatrixMethods!int"));

  template matrixMethods(T)
  {
    @method DenseMatrix!T _times(Matrix!T m, T s) { return new DenseMatrix!T; }
    @method DenseMatrix!T _times(T s, Matrix!T m) { return new DenseMatrix!T; }
    @method DiagonalMatrix!T _times(DiagonalMatrix!T m, T s) { return new DiagonalMatrix!T; }
    @method DiagonalMatrix!T _times(T s, DiagonalMatrix!T m) { return new DiagonalMatrix!T; }
  }

  mixin(registerMethods("matrixMethods!double"));
  mixin(registerMethods("matrixMethods!int"));

Now it would be nice if we could do away with the explicit instantiations...in theory it could be done - any time a method template is called, trigger the instantiation of all the templatized overrides -, but this is beyond the power of a library. Even with support at language level, it would probably require a pre-link phase.

I am going to sleep on this a couple more times before documenting it and officially support it. I will probably add an overload to registerMethods so we can say 'registerMethods!(matrixMethods!double)'; I don't like passing types as strings very much.

As always, comments and suggestions are encouraged.