为什么C ++要求复杂只能实例化为float,double或long double?

时间:2012-06-19 20:18:31

标签: c++ math language-design complex-numbers

根据C ++ ISO规范,§26.2/ 2:

  

未指定complexfloatdouble以外的任何类型实例化模板long double的效果。

为什么标准作者会明确添加此限制?这使得它未被指定,例如,如果您制作complex<int>complex<MyCustomFixedPointType>并且看起来像是人为限制会发生什么。

这种限制有原因吗?如果要使用自己的自定义类型实例化complex,是否有解决方法?

我主要是因为this earlier question而提出这个问题,其中OP对abscomplex<int>提供奇怪输出的原因感到困惑。也就是说,考虑到我们也可能希望用固定点类型,更高精度的实数等来制作complex数字,这仍然没有意义。

2 个答案:

答案 0 :(得分:30)

您无法在整数上正确实现许多std::complex操作。如,

template <class T>
T abs(const complex<T> &z);
当复数表示为(真实,成对)对时,<{1>} complex<long>不能有T = long返回值,因为它返回sqrt(pow(z.real(), 2) + pow(z.imag(), 2))的值。只有少数操作才有意义。

更糟糕的是,polar命名的构造函数在不破坏默认构造函数的情况下无法变得可靠,反之亦然。标准必须指定“复数整数”为Gaussian integers,以使它们具有任何用途,并且其中一个构造函数严重破坏。

最后,你希望你的“复数整数除法”如何服务,你想要一个“复杂的余数”吗? :)

总结一下,我认为指定一个单独的gaussian_int<T>类型比使用T上的整数std::complex的移植支持更为明智。

答案 1 :(得分:12)

可能与辅助函数兼容。例如:

template<class T> T abs (const complex<T>& x);

如果T == intabs将返回int,这意味着精确度会大幅下降。