From: Amitha Perera <perera@cs...>  20021001 18:57:13

Regardless of the ability to squeeze in an extra bool into vnl_vector, there are other fundamental problems. Brad and I discussed possible solutions and came up with: it can't be done. Kinda. (See 5 below for our proposed solution.) The biggest stumbling block concerns userdefined conversions and templates. (Aside: it seems that awf knew about all these issues during the initial vnl design. Why didn't you write them down? Sigh. :) ) 1. We cannot combine vnl_vector and vnl_vector_fixed with a union, because we would still need some flag variable => extra cost for vnl_vector_fixed. 2. vnl_vector needs to have size and data_ptr, and so cannot serve as a base class without adding this cost to the vnl_vector_fixed. 3. vnl_vector_fixed cannot serve as a base class, because that would imply all algorithms are written in terms on vnl_vector_fixed: template<class T, int N, int M> ... vnl_svd( const vnl_matrix<T,N,M>& ); This means many, many vnl_svd instantiations, and that's just the beginning of the problems with this approach! 4. Therefore, vnl_vector and vnl_vector_fixed should be unrelated via inheritance, and a user defined conversion can be created to convert a vnl_vector_fixed to a vnl_vector_ref whenever necessary. But: userdefined conversions are not (cannot be) attempted for templated functions. Thus, even if a conversion exists, template<class T> void f( const vnl_vector<T>& v ); ... vnl_vector_fixed<float> vf; f( vf ); would not work. (Error: f(vnl_vector_fixed<float>) not found.) 5. Our proposed solution: vnl_vector and vnl_vector_fixed are not related by inheritance. There is an explicit conversion from vnl_vector_fixed to vnl_vector_ref, which is a subclass of vnl_vector. Most routines will be written for vnl_vector, but will have an "automatic" overload for vnl_vector_fixed. For example, a header f.h delcaring function f would look something like: template<class T> void f( const vnl_vector<T>& v ); template<class T, int N> inline void f( const vnl_vector_fixed<T,N>& vf ) { f( vnl_as_vector_ref( vf ) ); } The f.txx will have the implementation of f(const vnl_vector<T>&). The advantages: (a) f need only be defined for vnl_vector<T>. Thus library need only have explicit instantiations for vnl_vector<double> and vnl_vector<float>. If the user calls f with vnl_vector_fixed<double,3>, the inline wrapper will automatically call the proper f after doing the conversion. (b) If f can be implemented efficiently for, say, vnl_vector_fixed<T,2>, an explicit specialization can coexist with the forwarding wrapper. vnl_vector_fixed<T,2> will call the special, efficient version while all other vnl_vector_fixed<T,n> will continue to use the wrapper. Question: is vnl_as_vector_ref() a good name for the explicit convertor, or is vf.ref() or vf.as_vec_ref() better? I think prefer the former because (1) it reads explicitly as a conversion and (2) it can potentially be extended to convert other types (e.g. vgl_vector to vnl_vector) while maintaining a consistent name. [ vgl_vector_2d vg; vnl_vector_fixed<float,2> vf; vnl_norm( vnl_as_vector_ref( vg ) ); vnl_norm( vnl_as_vector_ref( vf ) ); ] Thoughts? Amitha. 