【问题标题】:Is there a reason why implementations allow instantiation of std::complex with unsupported types是否有实现允许使用不受支持的类型实例化 std::complex 的原因
【发布时间】:2022-01-19 13:36:13
【问题描述】:

编辑说明: 最初的问题说 illegal 现在它说 unspecified

感谢 Jason Turner 视频的视频评论部分,我最近了解到 std::complex<int> 未指定。

但所有(AFAIK)实现似乎都happily compile

std::complex<int>

但是像std::abs() 这样的一些函数在std::complex&lt;int&gt; 中被破坏了,所以它在那些主流实现中实际上是不可用的。


我想知道为什么从未实现“坏”类型的检测是否有某些原因。我知道 std lib 实现需要使用较旧的标准,因此它们不能只是到处使用 std::floating_point 概念,甚至在 C++20 之前我们就有办法约束模板。

换句话说:这只是“会很好,但我们没有时间”的问题,还是有一些兼容性原因来保持这个编译。 我唯一能想到的是,有些人正在使用 std::complex 和 std lib “制造商”并不想明显破坏他们已经损坏的代码。

【问题讨论】:

  • 对于数学家来说,复数的“实部”和“虚部”并不一定是实数,更不用说它们是浮点数了。复数也是更一般概念的特例 - 例如超复数。
  • @Peter 我的猜测是他们不想处理返回浮点数/双精度数(不同类型)的绝对复数或整数复数。 std::hypot 修复了 AFAIK...en.cppreference.com/w/cpp/numeric/math/hypot (8)
  • 它编译但未指定并不意味着它会导致未定义的行为或其他疯狂的事情。如果它被实施,它将如何工作,这是供应商文档的一部分。如果您看一下 gcc STL 源代码,您会发现它按预期工作。它与 c++20 无关,也与概念或 is_floating_point 特征的存在无关。让它不编译也可以用 c++03 来完成。
  • @Klaus 它无法正常工作,std::abs 因 int 的复数而损坏。

标签: c++ language-lawyer c++20 complex-numbers unspecified-behavior


【解决方案1】:

其实并不违法,是未指明

来自[complex.numbers]/2

为浮点、双精度或长双精度以外的任何类型实例化模板复合体的效果是 未指定。

未指定,来自[defns.unspecified] 表示

未指定的行为 行为,对于格式良好的程序构造和正确的数据,这取决于实现 [条目注释 1:实现不需要记录发生的行为。的范围 本文档通常描述了可能的行为。 ——尾注]

(来自 N4860(C++20 草案)的引用

【讨论】:

  • 自 1998 年以来,所有 C++ 标准都未指定它。
  • 有了 C++20 中添加的概念,为什么复杂的模板没有被限制为浮点类型? ISO C++ 委员会是否给出了理由?
  • @UriRaz,因为允许实现具有用于其他类型的功能复杂类型;为什么要剥夺这种能力?
  • @ChrisMM 如果有用的话似乎是合理的,例如复杂的整数,它将被指定,否则被阻止。
【解决方案2】:

实现允许使用不受支持的类型实例化 std::complex 是否有原因?

我想知道为什么从来没有实现对“坏”类型的检测。

未指定的行为(您所描述的)和未定义的行为都很有价值,因为它们允许在未来的标准中出现新的行为。

如果未来的 C++ 标准要实现 long long doubledecimal 类型,那么也可以修改 std::complex 以支持它。

有一天,std::complex&lt;int&gt; 非常重要,未来的标准可能会承诺实施它。

相反,如果标准承诺“检测‘坏’类型”,那么这些修订不可能在不使 C++ 标准发生冲突的情况下发生。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-12-01
    • 1970-01-01
    • 2019-11-24
    • 1970-01-01
    • 2013-10-12
    • 2019-03-31
    • 2020-09-17
    • 2015-10-20
    相关资源
    最近更新 更多