[eigen] Re: VectorBase issue

[ Thread Index | Date Index | More lists.tuxfamily.org/eigen Archives ]



sorry, forgot the previous message, the send button got pressed accidentally... here is the complete one:

Hi list,

In order to properly discard vector specific features to the rest of the API (and at the same time slightly increase the compilation speed for matrix code) I tried to add a templated VecorBase base class from which MatrixBase would automatically inherit if the _expression_ is indeed a vector:

template<typename Derived> class MatrixBase
       : public VectorBase<Derived> { /*common API*/ };

template<typename Derived,
              bool IsVector=Derived:IsVector> class VectorBase { /*empty*/ };

template<typename Derived>
class VectorBase<Rerived,true>
{ /*vector specific API*/ };

This looks nice, but I unfortunately hit a couple of issues I'd like to discuss:

1 - first of all, since VectorBase inherits from nothing, we must duplicated the MatrixBase::derived() method and call it whenever we want to access a MatrixBase member. Actually I think this is good in general since it allows to overload a MatrixBase member in Derived, and the proper overload will be called. So maybe this is a rule we should use thorough eigen, i.e., for all methods defined in MatrixBase and for arguments defined as a MatrixBase ?

2 - the second issue is more annoying: C++ does not allow to overload a member of a base class with a different prototype, well this is allowed, but then the member of the base class won't be available through the derived class. Here an example:

class VectorBase { Scalar coeff(int); }:
class MatrixBase : public VectorBase { Scalar coeff(int,int) };

MatrixBase v; v.coeff(1); // won't compile

the same issue occurs with coeffRef and block which is defined as:
block(int start, int size);
in VectorBase and as
block(int startRow, int startCol, int rows, int cols);
in MatrixBase.

I see three solutions:

a - keep conflicting members in MatrixBase (but then we lost the purpose of VectorBase)

b - use different names, for instance:
      - VectorBase::coeff*(int) => VectorBase::at*(int)
      - VectorBase::block(int,int) => VectorBase::segment(int,int)
    but this might be a no-end issue and maybe not always very nice to have different names ?

c - define the overload in 2D matrix specific base class, i.e. in VectorBase<Derived,false>:
      class VectorBase<Derived,false> {
       Scalar coeff(int,int);
       etc.
      };
   However this approach makes impossible to write generic code on fixed-size matrix that might degenerate to vector of even 1x1 matrices...

3 - the last issue is that this approach makes impossible to write code like that:
   if (IsVectorAtCompileTime)
   {
   }
   else
   {
   }
   which has to be replaced by a meta selector. (not a big deal since meta selector are usually faster to compile)

So to conclude let me remind the current solution that is if a vector specific method is called on a non vector then an assertion is raised at runtime while this could be detected at run-time. Not too bad, but not very nice too.

So, any suggestion ? should I give up with VectorBase ? and if not, which options looks the best for issue 2 ?


cheers,
Gael.



Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/