[eigen] Re: VectorBase issue |
[ Thread Index |
Date Index
| More lists.tuxfamily.org/eigen Archives
]
- To: eigen@xxxxxxxxxxxxxxxxxxx
- Subject: [eigen] Re: VectorBase issue
- From: "Gael Guennebaud" <gael.guennebaud@xxxxxxxxx>
- Date: Tue, 3 Jun 2008 11:10:07 +0200
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:message-id:date:from:to:subject:in-reply-to:mime-version:content-type:references; bh=0dmAJvDjIlfi4rdpRav6XmmvcX1lby/e/r2HQp5tdXQ=; b=NtszJA3AHt7b1PPBqr4nI0Ta8jN8SUpPhefyLMhIL54wskrTtqnu0bHCm5cWIzjL9JKty50Q5W/hRgKz3oDyeNjRYX8poAm1jUASNMf4GZwu57nBEYYixkulUjxv9SA12PT1mRDfm/0mGGIqLadSn5yt/DmdEa2LUFFiqyudKto=
- Domainkey-signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=message-id:date:from:to:subject:in-reply-to:mime-version:content-type:references; b=x7aBo+1vhtF0BynUZxI6pnd2+xE9PjCKEUOOcPCZybKZqNDzicW9zEwLyjQ1ULiI3+lumrmI2VNHcKTuF2z7M6HiSiARfv65ImcxQkuauMFn5ocmMup+uzykPmxNXwg4ShzL2xORACHKmv3b2oLMTEfo3RjpdwnKNk12PpUId+g=
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.