c ++使用DenseBase的模板化函数中的特征块操作

时间:2017-09-22 09:14:47

标签: c++ eigen

这有效

Vector2d a(1,2);
VectorXd cc(10);
cc << 1.0, 2.0, 3, 4, 5, 6, 7, 8, 9;
VectorXd rr(10);
rr << 1.0, 2.0, 3, 4, 5, 6, 7, 8, 9;
int R(10);
Vector2d G(Vector2d::Zero());


G.noalias() -= cc.segment(4, 2) + 
               (rr.segment(1, 2) - R*Vector2d::Ones()).cwiseQuotient(a); // OK here

但是当rr.segment(1,2)作为参数传递给函数时,最后一行中的operator-不会编译。此代码中出现此问题

template <typename DerivedA, typename DerivedB, typename DerivedC>
void testFunc(MatrixBase<DerivedA>& G, const DenseBase<DerivedB>& c, const DenseBase<DerivedC>& r)
{  
   Vector2d a(1,2);
   int R(10);
   G.noalias() -= c + (r - R*Vector2d::Ones()).cwiseQuotient(a);
};

VectorXd cc(10);
cc << 1.0, 2.0, 3, 4, 5, 6, 7, 8, 9;
VectorXd rr(10);
rr << 1.0, 2.0, 3, 4, 5, 6, 7, 8, 9;
Vector2d G(Vector2d::Zero());
testFunc(G, cc.segment(4, 2), rr.segment(1, 2)); // ERROR : no match for 'operator-'

我理解问题在于,在testFunc()中,cc.segment被视为未实现运算符的一般DenseBase对象,尽管它是针对特定类.block()实现的。

1 个答案:

答案 0 :(得分:1)

您可以通过撰写DenseBasec.derived()告诉Eigen使用r.derived()类封装的实际类型。

不相关:而不是R*Vector2d::Ones()Vector2d::Constant(R),如果整个表达式是元素操作,那么你应该在Array域中工作:

template <typename DerivedA, typename DerivedB, typename DerivedC>
void testFunc(MatrixBase<DerivedA>& G, const DenseBase<DerivedB>& c, const DenseBase<DerivedC>& r)
{
   Array2d a(1,2);
   int R(10);
   G.array() -= c.derived().array() + (r.derived().array() - R)/a;
}

(如果您通过.derived()代替.array()ArrayBase

,则可以省略所有MatrixBaseDenseBase

此外,只有涉及矩阵产品时才需要.noalias()