Why? This might have been useful in C++ prior to templates, but generic
programming really offers a much more flexible approach. Straight-forward
generic programming would template algorithms on the "Matrix" and "Vector"
types and assume a particular interface for these types (standard "function"
names). However, one can use traits to provide an additional level of
indirection
(compile-time indirection) so standard function names are not even
required, just a particular set of capabilities. I highly recommend that
you take a look at Geoff Furnish's recent paper on this subject in
this month's Computers In Physics. For instance, all of the standard
function names that you discuss become standard traits in the library's
traits class:
template <class Matrix>
struct MatrixTraits { };
template <>
struct MatrixTraits<doubleMatrix>
{
typedef doubleMatrix Mat_t;
typedef doubleMatrix::Handle Handle_t;
static Handle_t handle(const Mat_t &m) { return m.handle(); }
static int offset(const Mat_t &m) { return m.offset(); }
static int stride1(const Mat_t &m) { return m.stride1(); }
static int length1(const Mat_t &m) { return m.length1(); }
// etc.
};
The algorithms then template off the Matrix type and perform all operations
on Matrix objects through the MatrixTraits members. For instance, here is a
really trivial example:
template <class Matrix>
void transpose(Matrix &a)
{
typedef MatrixTraits<Matrix> MT;
int i_start = MT::begin1(a);
int i_end = MT::end1(a);
int j_start = MT::begin2(a);
int j_end = MT::end2(a);
assert(j_end-j_start == i_end-i_start);
for (int i = i_start; i < i_end; ++i)
for (int j = j_start; j < j_end; ++j)
swap(a(i,j), a(j,i));
}
This will work with any "Matrix" class that has operator() overloaded for
indexing (one "standard" that we should all implement) and that has
specialized MatrixTraits to provide the begin1(), etc., operations.
So, rather than standardizing on names for classes and member functions,
all one needs to "standardize" on are the capabilities that a container
needs to have. The MatrixTraits class could be standardized, or every
library could provide its own MatrixTraits type of class, specifying only
those capabilities that that library needs, and leaving it up to the user
of the library to specialize this class as is appropriate for his containers.
> doubleComplexVector v(n);
Ack! There is no good reason for not writing generic containers - this is
generic programming at its most basic:
Vector< complex<double> > v(n);
Jim