简体   繁体   中英

Specialization of a member of a template class for a template class parameter type

I have a templated class Matrix. I want to specialize a function for the type complex, where T can be anything. I have tried this :

  6 template <typename T>
  7 class Matrix {
  8       public :
  9             static void f();
 10 };          
 11 template<typename T> void Matrix<T>::f() { cout << "generic" << endl; }
 12 template<> void Matrix<double>::f() { cout << "double" << endl; }
 13 template<typename T> void Matrix<std::complex<T> >::f() { cout << "complex" << endl; }

Line 13 does not compile. How can I do that ?

In lines 11 and 12 you have declaration of explicit specialization for a member of a class template which is allowed by C++ Standard 14.7/3 (14.5.2/2 contains a good example too). In line 13 you are trying to partially specialize a class template and that is not allowed in this form (this is partial specialization because you don't know the whole type std::complex<T> because it is still depends on T ). You should partially specialize the whole class.

In fact, I found a clever way to do it through Boost. Since I don't want my library to be dependant on Boost, here is the code :

template <class T, T val> struct integral_constant
{
      typedef integral_constant<T, val> type;
      typedef T value_type;
      static const T value = val;
};    
typedef integral_constant<bool, true>  true_type;
typedef integral_constant<bool, false> false_type;
template <typename T> struct is_complex : false_type{};
template <typename T> struct is_complex<std::complex<T> > : true_type{};

template <typename T>
class Matrix {
      public :
            static void f() { f_( typename is_complex<T>::type() ); }
      private :
            static void f_( true_type ) { cout << "generic complex" << endl; }
            static void f_( false_type ) { cout << "generic real" << endl; }
};          
template<> void Matrix<double>::f() { cout << "double" << endl; }

This way, I can use function overloading and template to achievement my goal.

As describe in the linked answer, what you'll need to do is specialize the entire class, rather than the simple function:

#include <iostream>
#include <complex>
using namespace std;

template <typename T>
class Matrix {
public :
    static void f();
};

template<typename T> void Matrix<T>::f() { cout << "generic" << endl; }
template<> void Matrix<double>::f() { cout << "double" << endl; }

template <typename T>
class Matrix<std::complex<T> > {
public:
    static void f() { cout << "complex" << endl; }
};

int main(void) {
  Matrix<complex<double> >::f();
  return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM