Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Remove non-generic template parameter on C

I'm using ublas for my matrix code, but I want it to be exchangeable, so I was doing this:

typedef boost::numeric::ublas::matrix<double> cMatrix;

Today, I need to change some of this matrixes to bounded sizes, so I will also have this:

typedef boost::numeric::ublas::bounded_matrix<double, 3, 3> Matrix3d;

The problem is that my old function declaration:

void cClass::function(int param1,
                      int param2,
                      cMatrix &param3,
                      int param4);

No longer works. It gives me:

error : a reference of type "cMatrix &" (not const-qualified) cannot be initialized with a value of type "Matrix3d"

I managed to fix it by changing the declaration to:

template <class A>
void cClass::function(int param1,
                      int param2,
                      boost::numeric::ublas::matrix<double, boost::numeric::ublas::row_major, A> &param3,
                      int param4);

The problem is that my definition is a cpp file, so I will have to do something like this in the cpp:

void dummyFunc()
{
  cClass dummy(NULL, NULL);
  cMatrix c;
  Matrix12d d12;
  dummy.function(-1, -1, c, -1);
  dummy.function(-1, -1, d12, -1);
}

Is there some way to avoid doing the dummyFunc or generalizing the function in other way?

like image 436
renatolond Avatar asked Nov 04 '22 08:11

renatolond


2 Answers

If both matrix and bounded_matrix have exactly the same API, you can abstract the type and generalize cClass::function using variadic templates:

template<template <class...> class M, class... Arg>
void cClass::function(int param1,
                      int param2,
                      M<Arg...> &param3,
                      int param4);
like image 60
Thibaut Avatar answered Nov 12 '22 18:11

Thibaut


I suggest this improvement over Thibaut's (correct) answer:

template<class UblasMatrix, typename /*Dummy*/ = UblasMatrix::array_type>
void cClass::function(int param1,
                      int param2,
                      UblasMatrix &param3,
                      int param4);

Thanks to SFINAE, the second template argument is just to be (almost) sure that you are calling the function with some kind of ublas matrix and not something else (like, let's say std::vector<doubel>). This avoids confusing error messages.

like image 45
alfC Avatar answered Nov 12 '22 18:11

alfC