Michael --- yes, they can be split up, but the problem is
that they all depend on the base class template, which
involves Eigen types. So there's no way to split them up
with inducing a dependency from /prim to /mat.
Barring a better solution, I'll just have to drop it all into
/mat and define the templated versions of functions there. It makes
sense in that it's where it would have to be defined anyway because
the top-level function depends on everything. What it disallows
is having a std::vector only version of the vectorization, but given
our main use case in Stan, that's no big deal.
Now, onto the C++ tutorial part of the email. Sorry in advance
if it's obvious---this took me a while to figure out.
You're both right. Yes, Michael, those are partial class template
specializations. Yes, Daniel, you can't do that with functions,
which is why I did it with classes and a simple templated wrapper
function.
That is, instead of a template function foo
template <typename T0, ..., TN>
T0 foo(T1, ..., TN);
which can be called directly as foo<T0,...,TN>(x1,...,xN),
I create a template class
template <typename T0, ..., TN>
struct foo_fun {
static T0 apply(T1, ..., TN);
}
and call foo_fun<T0,...,TN>::apply(x1,...,XN).
The upside is that it is order independent because of
the way class template specializations are resolved. The
downside is that you need to specify all those parameters
in the call and can't do type inference.
The latter problem's taken care of with the generic
wrapper function which passes the types of the arguments
(and function class name type parameter) through.
- Bob