5

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?

renatolond
  • 106
  • 1
  • 7
  • 3
    What's the purpose of that dummy function? Do you try to force that the template gets instanciated, because you get linker errors otherwise? – Sebastian Dec 12 '12 at 19:08
  • 1
    `<` http://stackoverflow.com/questions/2152002/how-do-i-force-a-particular-instance-of-a-c-template-to-instantiate `>` `<` http://www.comeaucomputing.com/techtalk/templates/#export `>` may be useful – Yakk - Adam Nevraumont Dec 12 '12 at 19:18
  • I tried changing the dummy for `template void cClass ::function(int param1, int param2, cMatrix &param3, int param4);` `template void cClass ::function(int param1, int param2, Matrix12d &param3, int param4);` But it continues to give linker errors. – renatolond Dec 12 '12 at 19:27

2 Answers2

1

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);
Thibaut
  • 2,400
  • 1
  • 16
  • 28
1

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.

alfC
  • 14,261
  • 4
  • 67
  • 118