This forum has been archived. All content is frozen. Please use KDE Discuss instead.

Help with templated classes and functions

Tags: None
(comma "," separated)
mbraun92
Registered Member
Posts
10
Karma
0
Hi. I am having some difficulty writing templated classes that have Eigen matrices as members, and writing function members to those classes. Consider the code that is pasted below. In it, there are two classes that do the same thing: store references to A (a lower triangular matrix) and x (a vector). The myFunc function solves A'x for x, and returns the result.


Code: Select all
#include<Eigen/Core>

using namespace Eigen;
using namespace std;

#define NOTEMPLATED

#ifndef NOTEMPLATED

template<class Derived>
class MyClass {

public:

  const MatrixBase<Derived>& A;
 
  Vector3d& x;
  MyClass(const MatrixBase<Derived>&, Vector3d&);
  void myFunc(Vector3d&);
};

template<class Derived>
MyClass<Derived>::MyClass(const MatrixBase<Derived>& A_, Vector3d& x_) : A(A_), x(x_) {}

template<class Derived>
void MyClass<Derived>::myFunc(Vector3d& out) {

  cout << A << endl << endl;
  cout << x << endl << endl;

  out = A.triangularView<Lower>().transpose().solve(x);
}

#endif


class MyClass2 {

public:

  const Matrix3d& A;
  Vector3d& x;
  MyClass2(const Matrix3d&, Vector3d&);
  void myFunc(Vector3d&);
};

MyClass2::MyClass2(const Matrix3d& A_, Vector3d& x_) : A(A_), x(x_) {}

void MyClass2::myFunc(Vector3d& out) {

  cout << A << endl << endl;
  cout << x << endl << endl;

  out = A.triangularView<Lower>().transpose().solve(x);

}

int main() {

  Matrix3d A;
  A << 1,0,0,
    2,4,0,
    3,5,6;

  Vector3d x;
  x << 2,1,4;

#ifndef NOTEMPLATED
 
  Vector3d out1;
  MyClass<Matrix3d> C1(A, x);
  C1.myFunc(out1);
  cout << out1;
 
#endif

  Vector3d out2;
  MyClass2 C2(A, x);
  C2.myFunc(out2);
  cout << out2 << endl;
}




The difference between them is that MyClass is templated, but MyClass2 is not. MyClass2 works fine (when I define NOTEMPLATED so MyClass is not compiled). But when I compile with MyClass, I get the following error:


Code: Select all

~/Documents/dists/eigen $ g++ -I/Users/braunm/Install_Files/eigen-eigen-3.0.1 test.cpp -o test
test.cpp: In member function 'void MyClass<Derived>::myFunc(Eigen::Vector3d&)':
test.cpp:28: error: expected primary-expression before ')' token
test.cpp: In member function 'void MyClass<Derived>::myFunc(Eigen::Vector3d&) [with Derived = Eigen::Matrix<double, 3, 3, 0, 3, 3>]':
test.cpp:68:   instantiated from here
test.cpp:28: error: no match for 'operator<' in '((MyClass<Eigen::Matrix<double, 3, 3, 0, 3, 3> >*)this)->MyClass<Eigen::Matrix<double, 3, 3, 0, 3, 3> >::A->Eigen::MatrixBase::triangularView [with unsigned int Mode = Mode, Derived = Eigen::Matrix<double, 3, 3, 0, 3, 3>] < Lower'


If I remove the triangularView<Lower>() part, I would then get a message saying that there is no member solve().

I'm really new to templates (and C++, for that matter), so I'm not sure what to do here.

Note that I have tried to follow, as best I can, the instructions on the "Writing Functions that Take Eigen Types as Parameters" help page. But that also led to a second question. In MyClass, there is only one template parameter, Derived. In the example for storing the result on the help page, there is another template parameter, OtherDerived. The examples on the page seem to address only templated functions, but not functions that are members of templated classes. So what would I do in this case?

Thanks in advance for your help with this, and for creating the library. I am still brand new to Eigen, but I am excited to use it.


Michael
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS
you have to use the C++ template keyword:


out = A.template triangularView<Lower>().transpose().solve(x);


It works as the typename keywords (e.g., typename Derived::Scalar) but for members rather than types.
mbraun92
Registered Member
Posts
10
Karma
0
Thank you, that did the trick. I have never seen the template keyword used in that way before, and a search through various C++ resources (both online and offline) yielded nothing as well. Can you point me towards a general explanation of when the .template keyword is needed? And might I suggest adding this to the tutorial?

Thanks again.
mattd
Registered Member
Posts
28
Karma
0
mbraun92 wrote:Thank you, that did the trick. I have never seen the template keyword used in that way before, and a search through various C++ resources (both online and offline) yielded nothing as well. Can you point me towards a general explanation of when the .template keyword is needed? And might I suggest adding this to the tutorial?


The best explanation is in the Appendix B ("The typename and template Keywords") of the "C++ Template Metaprogramming" by David Abrahams, Aleksey Gurtovoy.

If you don't have it handy, you can look at the following explanations:
http://pages.cs.wisc.edu/~driscoll/typename.html
http://www.parashift.com/c++-faq-lite/t ... #faq-35.18
http://www.comeaucomputing.com/techtalk ... lateprefix
http://www.comeaucomputing.com/techtalk ... /#typename
mbraun92
Registered Member
Posts
10
Karma
0
Thanks. Those are helpful references.


Bookmarks



Who is online

Registered users: Bing [Bot], Google [Bot], Yahoo [Bot]