Soo
Soo

Reputation: 1017

Template specialization for template

I have a function which uses the Eigen C++ library:

 template <class Type1>
 void myFunction ( const Eigen::MatrixBase<Type1>& matrix)
 {

 }

Now, I would like to specialize the template function "myFunction" for the type std::complex<Type>. Note that the type "std::complex<Type>" is again a template. How to define such a function?

Upvotes: 0

Views: 121

Answers (2)

chtz
chtz

Reputation: 18807

You have to note that Eigen::MatrixBase<std::complex<...> > is not a valid type, since MatrixBase is a CRTP-base class. E.g., Matrix<double,2,2> inherits (indirectly) from MatrixBase<Matrix<double,2,2> >, etc. However, every MatrixBase provides a Scalar type which you can check using SFINAE (i.e., using std::enable_if):

template <class Derived>
typename std::enable_if<Eigen::NumTraits<typename Derived::Scalar>::IsComplex, void>::type 
myFunction(const Eigen::MatrixBase<Derived>& matrix) {
    std::cout << "Passed complex\n";
}

template <class Derived>
typename std::enable_if<!Eigen::NumTraits<typename Derived::Scalar>::IsComplex, void>::type 
myFunction(const Eigen::MatrixBase<Derived>& matrix) {
    std::cout << "Passed non-complex\n";
}

Godbolt-Demo: https://godbolt.org/z/Q9YlPz

Upvotes: 1

R Sahu
R Sahu

Reputation: 206577

You can overload myFunction as:

template <class Type1>
void myFunction ( const Eigen::MatrixBase<std::complex<Type1>>& matrix)
{
}

Don't think of it as a specialilzation of the first function. It's just an overload.

The following program demonstrates the concept using Foo.

#include <iostream>
#include <complex>

template <typename T>
struct Foo
{
};

template <typename T>
void myFunction ( const Foo<T>& f)
{
   std::cout << "In myFunction(const Foo&)\n";
}

template <typename T>
void myFunction ( const Foo<std::complex<T>>& f)
{
   std::cout << "In myFunction(const Foo<std::complex>&)\n";
}

int main()
{
   myFunction(Foo<int>());
   myFunction(Foo<std::complex<int>>());
}

Output:

In myFunction(const Foo&)
In myFunction(const Foo<std::complex>&)

Upvotes: 0

Related Questions