2017-09-22 4 views
0

Cela fonctionneC++ propres opérations de bloc dans les fonctions templated prenant DenseBase

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 

mais quand rr.segment (1, 2) est passé comme argument d'une fonction, la operator- dans la dernière ligne ne compile pas . Le problème se produit dans ce code

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-' 

Je comprends que le problème est dans le fait que, dans TestFunc(), cc.segment est considéré comme un objet DenseBase général pour lequel le operator- n'est pas mis en œuvre, bien qu'il soit implémenté pour la classe particulière .block().

+0

L'implémentation de testFunc fonctionne sur des expressions matricielles, donc il faut prendre des arguments MatrixBase <> (c'est-à-dire que l'ajout d'un Vector2d est une opération matricielle). Pourquoi prenez-vous DenseBase <>? –

+0

parce que je passe .block() comme arguments – itQ

+0

AFAIR, un bloc d'une expression matricielle est toujours une expression de matrice, par conséquent devrait correspondre à MatrixBase <> ... (ie, en remplaçant DenseBase <> par MatrixBase <> dans votre code compile d'ailleurs pour moi) –

Répondre

1

Vous pouvez indiquer à Eigen d'utiliser le type réel encapsulé par la classe DenseBase en écrivant c.derived() et .

non apparentés: Au lieu de R*Vector2d::Ones() écrire Vector2d::Constant(R), et si l'expression entière est des opérations élément par élément, vous devez travailler dans le domaine Array de toute façon:

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; 
} 

(Vous pouvez laisser toutes .derived() et .array() si vous passé ArrayBase au lieu de MatrixBase ou DenseBase)

en outre, le .noalias() est nécessaire que s'il existe des produits de matrice impliqués.