lundi 26 septembre 2016

C++ Varaidic Tempate with Eigen, overloading functions with parameter list gives unexpected result

I have been testing C++ templating within Eigen and have come across a problem while developing when using tempates and templated parameter lists. As per the following example, the "Function 2" is printed for all calls - even though the 3rd and 4th call perfectly match the prototype. It seems that the templated parameter list takes precedence due to an ambiguity. Now the interesting part is that this only happens when matrices are wrapped in "Eigen::MatrixBase", if I send matrices directly it is not a problem. But this would not be optimal for the expression templates being used.

Could someone explain the reason for this when using MatrixBase and what could be a workaround? I understand that giving one function a different name will do the trick, but then the function will loose generality. Is there a better way to fix it?

Thank you for your time!

Minimal example showing the effect:

typedef Eigen::Matrix<float, 2, 2> QType;
typedef Eigen::Matrix<float, 1, 1> UType;

template <typename... ParamsType>
void fun(const Eigen::MatrixBase<QType> &Q,
         const Eigen::MatrixBase<UType> &U,
         const ParamsType & ...params)
{
  cout << "Function 1" << endl;
}

template <typename... ParamsType>
void fun(const Eigen::MatrixBase<QType> &Q,
         const ParamsType & ...params)
{
  cout << "Function 2" << endl;
}

template <typename... ParamsType>
void fun2(const QType &Q,
          const UType &U,
          const ParamsType & ...params)
{
  cout << "Function 1" << endl;
}

template <typename... ParamsType>
void fun2(const QType &Q,
          const ParamsType & ...params)
{
  cout << "Function 2" << endl;
}

int main(int argc, char *argv[])
{
  QType Q = QType::Random();
  UType U = UType::Random();

  int param = 0;

  fun(Q);
  fun(Q, param);
  fun(Q, U);
  fun(Q, U, param);

  fun2(Q);
  fun2(Q, param);
  fun2(Q, U);
  fun2(Q, U, param);

  return 0;
}

Output:

Function 2
Function 2
Function 2
Function 2

Function 2
Function 2
Function 1
Function 1

Aucun commentaire:

Enregistrer un commentaire