以下代码具有类型转换错误
#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 ++无法处理上述代码。
任何人都可以为我解释这个吗?
答案 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
)来调用它。 j
和double
的类型不同,因此模板参数推断失败。
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,并且代码将被编译。