From: Amitha Perera <perera@cs...>  20030225 21:05:27

On Tue 25 Feb 2003, Paul Smyth wrote: > I had written an number of functions which perform operations on fixed size > vectors and matrices, and which took vector_fixed_ref and matrix_fixed_refs > as arguments. (As vector_fixed was derived from vector_fixed_ref, these > functions could operate on vector_fixed also). > Now that the two fixedsize classes have been taken out of the heirarchy, it > is now difficult/impossible to use a vector_fixed as a vector_fixed > ref. Yes. :( > e.g. > T my_dot_product(const vnl_vector_fixed_ref<T,n> & a ,const > vnl_vector_fixed_ref<T,n> & b) > void f() > { > vnl_vector_fixed<double,3> a,b; > double d = my_dot_product(a,b); > } > now doesn't compile. However, double d = my_dot_product( a.as_ref(), b.as_ref() ); should compile. Actually, you would need to implement as_fixed_ref() to do exactly what you want. > 1) Am I being reasonable wanting this behaviour? I think it is reasonable to ask for a vnl_vector_fixed_ref<T,n>. However, it is not clear what that entails, as I write below. > 2) What can I do to get this behaviour again? You would probably need to implement a separate class. See below. > 3) I'd like to make these fixedref classes standalone/lightweight, and no > longer derived from vnl_vector_ref etc. for speed/inlining & simplicity. Is > that mad? N.B. They are currently derived from vnl_vector_ref<T>, > vnl_matrix_ref<T> I think they would pretty much have to be. > I've tried adding "operator vnl_vector_fixed_ref<T,n>()" to vnl_vector_fixed > to do automatic casts. These don't seem to work, at least under > MSCV6. Unfortunately, userdefined conversion operators are not used when calling templated functions, so the only "conversion" that can happen is a derived>base conversion. Hence the need for vnl_vector_fixed::as_ref(). (Look at the documentation there.) > Obviously, one could make vnl_vector_fixed_ref a base class to > vnl_vector_fixed, at the cost of adding sizeof(T*) to the size of > vnl_vector_fixed. I presume this is not desirable, given the amout of > trouble that was gone to in order to minimise > sizeof(vnl_vector_fixed). The whole point of the change was to avoid the extra sizeof(T*) storage. In particular, the ITK community would like to store collections of millions of these, so every byte counts. > Lots of built in algorithms in vnl_matrix_fixed.h that currently operate on > vnl_matrix_fixed or vnl_vector_fixed might operate on fixed size reference > types instead. Do people care about this at all? I do, but I don't have the time to fix it correctly. My thoughts on the design:  vnl_vector_fixed<T,n> must be exactly sizeof(T)*n bytes. This means that there is no way for it to masquerade as a vnl_vector_fixed_ref<T,n>.  We can get a slightly better design by implementing a policybased vector. Brad King at Kitware suggested some things along this line when he and I were discussing the changes the vnl, but it didn't pan out. I have some newer ideas that may make it work. The biggest drawback is functions that used to use vnl_vector_fixed<T,n> would now need to use vnl_vector_fixed<T,n,AllocationPolicy> Something like template<class T, unsigned n, class Policy> vnl_vector_fixed_general { ... }; template<class T, unsigned n> vnl_vector_fixed : public vnl_vector_fixed_general<T,n,LocalSpace> {...}; template<class T, unsigned n> vnl_vector_fixed_ref : public vnl_vector_fixed_general<T,n,ExternalSpace> {...}; may make the transistion easier. Actually, template<class T, unsigned n, class Policy=LocalSpace> vnl_vector_fixed {...}; may work and be automatically backward compatible.  The best solution is probably to have a vnl_vector<T,Policy> and a vnl_vector<T,n,Policy>, with derived classes for backward compatibility. All the functions in vnl should be templated over the policy.  Using a policy template parameter may create practical problems, though, because compilers are broken. For example, witness the current hacks in vnl_matrix_fixed.h to get matrixmatrix multiplication working for fixed matrices in VC6. Amitha. 