I have the following defintions
template <typename T1, typename T2> class ArithmeticType {
public:
T1 x1;
T2 x2;
typedef typeof(x1+x2) Type;
};
template <typename D1, typename D2> inline
std::complex<typename ArithmeticType<D1,D2>::Type>
operator+(const std::complex<D1>& x1, const std::complex<D2>& x2) {
D1 x1r = real(x1);
D1 x1i = imag(x1);
D2 x2r = real(x2);
D2 x2i = imag(x2);
return std::complex<typename ArithmeticType<D1,D2>::Type>(x1r+x2r, x1i+x2i);
}
I then use this class as follows
std::complex<double> x;
std::cout << typeid(x).name() << std::endl;
ArithmeticType<std::complex<double>,std::complex<float>>::Type y;
std::cout << typeid(y).name() << std::endl;
which the produces output
St7complexIdE
St7complexIdE
which makes sense to me: y is of type std::complex<double>
Now, with the indent of adding complex and floating types, I add a specialization of the operator+ template so the code becomes
template <typename T1, typename T2> class ArithmeticType {
public:
T1 x1;
T2 x2;
typedef typeof(x1+x2) Type;
};
template <typename D1, typename D2> inline
std::complex<typename ArithmeticType<D1,D2>::Type>
operator+(const std::complex<D1>& x1, const std::complex<D2>& x2) {
D1 x1r = real(x1);
D1 x1i = imag(x1);
D2 x2r = real(x2);
D2 x2i = imag(x2);
return std::complex<typename ArithmeticType<D1,D2>::Type>(x1r+x2r, x1i+x2i);
}
template <typename D1, typename D2> inline
std::complex<typename ArithmeticType<D1,D2>::Type>
operator+(const std::complex<D1>& x1, const D2 x2) {
D1 x1r = real(x1);
D1 x1i = imag(x1);
return std::complex<typename ArithmeticType<D1,D2>::Type>(x1r+x2, x1i+x2);
}
I run the same code as before but now I get a compile error because the compiler tries to use the second specialization instead of the first. This doesn't make sense to me. I would think that the (g++) compiler would still choose the first specialization.
Can some explain the rule why this occurs?