behzad.nouri
behzad.nouri

Reputation: 77951

why type casting doesn't work in here?

The following code has type casting error

#define IMG_I (std::complex<double>(0, 1))
#define PI 3.1415926535
for (unsigned long int j = 0; j < 10; ++j)
  std::cout << exp(-IMG_I * PI * j);

The type casting can be easily solved by using extra parenthesis or changing the order of multiplication. But it is not clear for me why the type casting problem occurs in the first place and why the c++ cannot handle the above code as it is.

can anyone explain this for me?

Upvotes: 0

Views: 346

Answers (2)

Electric Wig
Electric Wig

Reputation: 334

If you look at the header file defining complex:

template
inline complex<_Tp>
operator*(const complex<_Tp>& __x, const _Tp& __y)
{
complex<_Tp> __r = __x;
__r *= __y;
return __r;
}

You'll see that instead of accepting a _Tp (in this case a double), the second parameter is a const _Tp&. This means that C++ is unwilling to perform the implicit cast from the integer j, hence the error.

If the second parameter were rewritten as a _Tp, C++'s built-in implicit type conversion would cast the integer to a double, and your code would compile.

Upvotes: 0

James McNellis
James McNellis

Reputation: 355069

This operator* overload for std::complex is a function template with a declaration that looks like:

template<typename T> 
complex<T> operator*(const complex<T>& lhs, const T& val); 

The T in complex<T> for the lhs argument must be the same as the T for the val argument in order for template argument deduction to work.

You are trying to call it with a std::complex<double> (the type of -IMG_I * PI) and an unsigned long (the type of j). double and unsigned long are not the same type, so template argument deduction fails.

-IMG_I * (PI * j) works because the type of PI * j is double, so there is no ambiguity as to what T is. Likewise, -IMG_I * PI * static_cast<double>(j) works for the same reason.

Upvotes: 8

Related Questions