为什么类型铸造在这里不起作用?

时间:2011-02-23 19:07:34

标签: c++ casting

以下代码具有类型转换错误

#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);

通过使用额外的括号或改变乘法的顺序,可以很容易地解决类型转换。但是我不清楚为什么首先出现类型转换问题以及为什么c ++无法处理上述代码。

任何人都可以为我解释这个吗?

2 个答案:

答案 0 :(得分:8)

operator*的{​​{1}}重载是一个函数模板,其声明如下:

std::complex

template<typename T> complex<T> operator*(const complex<T>& lhs, const T& val); 参数的T中的complex<T>必须与lhs参数的T相同才能使模板参数推断起作用

您尝试使用val(类型std::complex<double>)和-IMG_I * PI(类型unsigned long)来调用它。 jdouble的类型不同,因此模板参数推断失败。

unsigned long有效,因为-IMG_I * (PI * j)的类型为PI * j,因此double的含义不存在歧义。同样,T也是出于同样的原因。

答案 1 :(得分:0)

如果你看一下定义复杂的头文件:

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

您会看到,而不是接受_Tp(在这种情况下为双倍),第二个参数是const _Tp&。这意味着C ++不愿意从整数j执行隐式转换,因此错误。

如果第二个参数被重写为_Tp,则C ++的内置隐式类型转换会将整数转换为double,并且代码将被编译。