shoelz
shoelz

Reputation: 55

Template specialization for Eigen3 classes

I'm trying to implement templates to work with Eigen3 matrices and arrays. Generally, my implementation seems to be working just fine, but I fail to extend my implementation via template spezialization, to be able to either use Eigen3 types or standard numeric types (e.g. int, float, ...).

This is a shortened version of my current code:

#include <Eigen/Dense>
using namespace Eigen;

template<typename T>
void myFunc(Eigen::MatrixBase<T>& matrix)
{
  cout << "Eigen type" << endl;
}
template<typename T>
void myFunc(T& matrix)
{
  cout << "numeric type" << endl;
}

void main (void)
{
  int var=9;
  Eigen::Matrix<double,1,1> mat;

  myFunc(mat);  // This should uset the first template, but it doesn't !
  myFunc(var);
}

This compiles fine but when I run this, both calls to myFunc will be directed to the second template (-> "numeric type"), which is of course not what I want to achieve.

Any hints on solving this issue would be greatly appreciated.

Sebastian

PS: Using MSVC 2012

Upvotes: 1

Views: 236

Answers (2)

shoelz
shoelz

Reputation: 55

first of all thanks to your rapid response.

Over the weekend I did take a look at your suggestions and finally arrived at a solution, which compiles in VS2012 as well as newer gcc compiler versions (tested online ...). In the above code I changed the second template to the following:

template<typename T,
          typename std::enable_if<std::is_arithmetic<Derived>::value >::type* dummy = 0>
void myFunc(T& var)
{
  cout << "numeric type" << endl;
}

Not being an experienced C++ programmer, I have to admit that I'm surprised on how difficult (at least for me ...) it was to achieve such a relatively simple task. Guess I still have a long way to go ... :-)

Upvotes: 0

Pezo
Pezo

Reputation: 1448

The second function is chosen because it's a better match than the first when instantiated with Eigen::Matrix<double,1,1> as T. You need to constrain the second function so it's only valid with the types you intend. Have a look at std::enable_if, the examples on that page have pretty much exactly what you want.

If you want to learn more also look into SFINAE in general, that's what std::enable_if does.

Upvotes: 1

Related Questions