Partially specification in method of a class with more than two templates

72 Views Asked by At

I have a class with more than two templates. Now a method has to be specialized for two of these templates. As a minimal example I calculate in a method of a class the product of two numbers and take the real part. The number shall be complex or double. But the class has overall three templates. Here is the code for this:

#include <complex>
#include <cmath>

template<typename T1, typename T2, typename T3>
class A{
    public:
        A(T1 const & a_, T2 const & b_, T3 const & c_);

    double multiply_and_real();

    private:

    T1 const & a;
    T2 const & b;
    T3 const & c;
};

template<typename T3>
class A: public A<double,double,T3> {};

template<typename T1, typename T2, typename T3>
A<T1,T2,T3>::A(T1 const & a_, T2 const & b_, T3 const & c_):
    a(a_),
    b(b_),
    c(c_)
    {}

template<typename T3>
double A<double,double,T3>::multiply_and_real(){

    return a*b;
}

template<typename T3>
double A<std::complex<double>,double,T3>::multiply_and_real(){

    return a.real()*b;
}

template<typename T3>
double A<double,std::complex<double,T3> >::multiply_and_real(){

    return a*b.real();
}

template<typename T3>
double A<std::complex<double,T3>,std::complex<double> >::multiply_and_real(){

    return a.real()*b.real();
}


template class A< double, double,double >;
template class A< std::complex<double>, double ,double >;
template class A< double,std::complex<double> ,double >;
template class A< std::complex<double>,std::complex<double> ,double >;

template class A< double, double,std::complex<double> >;
template class A< std::complex<double>, double ,std::complex<double> >;
template class A< double,std::complex<double> ,std::complex<double> >;
template class A< std::complex<double>,std::complex<double> ,std::complex<double> >;


int main(){


    return 0;
}

The errors are of the kind:

main3.cpp:19:7: error: redeclared with 1 template parameter
class A: public A<double,double,T3> {};

main3.cpp:5:7: note: previous declaration ‘template<class T1, class T2, class T3> class
A’ used 3 template parameters class A{

I also tried out to specify directly the class in the following manner:

template<typename T3> class A< double, double,T3>;
template<typename T3> class A< std::complex<double>, double ,T3>;
template<typename T3> class A< double,std::complex<double> ,T3 >; 
template<typename T3> class A< std::complex<double>,std::complex<double> ,T3 >;

But this still gives the "redeclared" error.

1

There are 1 best solutions below

1
On BEST ANSWER

the error comes from line 19, where you define a new template class A with one template parameter, which inherits from the template class A with three parameters. This new class cannot have the same name as the old one, that's why the compiler complains.

If your real application has a similar structure to this one, you could save some code by defining a simple function such as

template <typename T>
double real_part(T a) {
    return 0;
}

template <>
double real_part(double a) {
    return a;
}

template <>
double real_part(std::complex<double> a) {
    return a.real();
}

Then you don't need to specify different versions of multiply_and_real at all. You could just define it as

template<T1, T2, T3>
double A<T1, T2, T3> >::multiply_and_real() {
    return real_part(a) * real_part(b);
}