【问题标题】:Why does C++ mandate that complex only be instantiated for float, double, or long double?为什么 C++ 要求仅针对 float、double 或 long double 实例化该复数?
【发布时间】:2012-06-19 20:18:30
【问题描述】:

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

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

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

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

我之所以问这个问题主要是因为 this earlier question,其中 OP 对为什么 abscomplex<int> 提供奇怪的输出感到困惑。也就是说,这仍然不太有意义,因为我们还可能希望将 complex 数字从定点类型、更高精度的实数等中提取出来。

【问题讨论】:

  • 看到你之前的回答我不禁笑了,但这确实是个好问题。
  • @chris- 在无法给出高层次理由的情况下给出这个答案我感觉很糟糕。我通常很擅长说“由于 X、Y 和 Z 的原因,这是 C++ 的一个奇怪的边缘案例”,但这次我不知道发生了什么。
  • “标准化复合体 已经在委员会上断断续续地讨论了十多年,至少有一个供应商对此表示强烈反对。” lists.cs.uiuc.edu/pipermail/cfe-dev/2012-March/020398.html
  • @HristoIliev- 为任意类型实现complex 困难这一事实并不一定意味着它应该不可能所以。 C++ 规范可能已经定义了一组新的特征(类似于容器要求或分配器要求)说“如果您可以实现以下内容,那么您可以存储在 complex 中。”
  • “未指定”与“未定义”或“格式错误”不同。未指定,在标准中,意味着“这可能是合法的,但标准并不要求它,你需要检查你的编译器文档,看看它在你的实际实现中是否允许。”

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


【解决方案1】:

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

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

当复数表示为 (real,imag) 对时,complex&lt;long&gt; 不能有 T = long 返回值,因为它返回 sqrt(pow(z.real(), 2) + pow(z.imag(), 2)) 的值。只有少数操作有意义。

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

最后,您希望如何处理您的“复整数除法”,以及您是否希望得到“复余数”? :)

总而言之,我认为指定一个单独的 gaussian_int&lt;T&gt; 类型并只进行一些操作比将整数 T 移植到 std::complex 上的支持更为明智。

【讨论】:

  • 有趣的是我们如何选择完全相同的函数来说明。 :)
  • 感谢您为这个决定提供了坚实的数学理由。我认为这为这个决定提供了一个优雅的理论理由。我以前没有听说过高斯整数,所以感谢您提出它们!
  • @templatetypedef:感谢您的提问并 +1。我从来没有考虑过当complex 被模板化为整数类型时会发生什么。 [不过,我不是数学家,如果有人能证明我在这方面错了,请这样做。]
  • 我知道这只是修辞上的意思,但高斯整数是欧几里得域(甚至是范欧几里得),因此余数除法的行为与普通整数的行为基本相同;你只是有更多的舍入模式选择。
【解决方案2】:

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

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

如果T == intabs 将返回int,这将意味着精度的巨大损失。

【讨论】:

  • 我们已经接受了整数除法的大量精度损失。 5/3 = 1。我认为我们同样可以接受abs(std::complex&lt;int&gt;(5, 3)) 返回56。这可能是一个利基市场,但我的大部分职业生涯都在处理复杂的整数。对于像我这样的人,不支持他们真是太可惜了。
猜你喜欢
  • 2013-07-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-25
  • 1970-01-01
  • 2018-11-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多