Reputation: 2134
Consider this bit of code:
#include <iostream>
#include <complex>
int main()
{
std::complex<double> z1 = 5;
std::cout << z1 - 1 << "\n"; // must change to z1 - 1.0 to compile
std::complex<int> z2 = 5;
std::cout << z2 - 1.0 << "\n"; // must change to z2 - 1 to compile
}
This produces a compilation error, as no operator-
is found for types in the expressions z1 - 1
or z2 - 1.0
. On the other hand, changing these expressions so that the base types match works fine.
Naively, for z1 - 1
I would expect the int
1 to be promoted to a double
, and expected the z2
, with base type int
, in z2 - 1.0
to be promoted to a complex<double>
. What's going on?
Upvotes: 7
Views: 2385
Reputation: 109289
The operator-
you're trying to invoke is a function template with a single type template parameter.
template< class T >
complex<T> operator-( const complex<T>& lhs, const T& rhs);
Neither of the template parameters in the two function parameters appears in a non-deduced context, so template argument deduction is performed on both parameters individually, and this results in the T
for lhs
being deduced as double
, while that for rhs
is deduced as int
.
Due to this mismatch between the deduced types, template argument deduction fails, and your code doesn't compile.
Upvotes: 6
Reputation: 67849
The compiler will not automatically convert types from A to B to C if A is integral and B is floating-point. You want the compiler to convert from int
-> double
-> complex<double>
, but it won't do that.
For the second example, you would need to promote the complex<int>
to a complex<double>
, which is not automatically handled by the complex
class template.
Upvotes: 1