问题标签 [spaceship-operator]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
0 回答
50 浏览

c++ - 为什么宇宙飞船操作员不允许我执行相等操作但允许不等式操作?

有谁知道为什么我在具有 3 路运算符覆盖的类上的相等操作出现编译器错误?我正在使用 VS 2019。

我收到上述行的错误: NativeConsoleApp.cpp(68,20): error C2676: binary '==': 'Rectangle' does not defined this operator or a conversion to an type接受预定义的运算符

编辑:请注意非默认运算符 <=> 的解释不会生成 == 和 C++20 中的 !=并没有解决不等式运算符有效但相等运算符无效的原因。

编辑:一个月后重读后,上面的链接现在有意义了。

0 投票
1 回答
5007 浏览

c++ - C++20 行为用相等运算符破坏现有代码?

我在调试这个问题时遇到了这个问题

我一直将其修剪为仅使用Boost Operators

  1. 编译器资源管理器C++17 C++20

    该程序可以在 GCC 和 Clang 中使用 C++17(启用 ubsan/asan)编译和运行良好。

  2. 当您将隐式构造函数更改为 时explicit,有问题的行显然不再在 C++17 上编译

令人惊讶的是,这两个版本都在 C++20 (v1v2上编译,但它们导致在 C++17 上无法编译的两行上的无限递归(崩溃或紧密循环,取决于优化级别)。

显然,这种通过升级到 C++20 潜入的无声 bug 令人担忧。

问题:

  • 这是否符合 c++20 行为(我希望如此)
  • 究竟是什么干扰?我怀疑这可能是由于 c++20 的新“宇宙飞船操作员”支持,但不明白它如何改变这段代码的行为。
0 投票
1 回答
141 浏览

c++ - C++20 宇宙飞船运算符的性能问题?

从 C++20 开始,标准库使用spaceship 运算符来实现字符串和向量的比较(根据此视频)。我担心这会带来潜在的巨大性能损失!

让我解释一下运算符的!=示例string

  • 当我编写str1 != str2时,编译器现在将其转换为(str1 <=> str2) != 0.
  • 然而,一个有效的!=for实现string将首先检查 for str1.size() != str2.size(),并且只有在失败时才转移到比较实际字符。
  • 这种优化无法为 spaceship 运算符实现,因为无论如何它都必须确定“更大”的字符串。

因此,如果这确实是现在比较字符串的不等式,这不是巨大的性能损失吗?

0 投票
1 回答
340 浏览

c++ - 继承的综合比较运算符产生警告/错误:ISO C++20 考虑使用重载运算符 '!='

在以下代码片段中,clang 11.0.1 生成警告

实时代码: https ://godbolt.org/z/65zWEq

上面的代码可以使用 Visual C++ (VS 16.8.x) 和以前的预览版 (VS 16.9.0 Preview 2) 成功编译。但是,最近发布的 VS 16.9.0 Preview 3 现在会为此代码片段产生错误:

看起来没有为iterator具有 CRTP 类的派生类提供综合比较运算符的合规方法iterator_facade吗?

0 投票
1 回答
272 浏览

c++ - 模棱两可的重载运算符 C++20

我正在尝试在最新的 Visual Studio 和 Clang 版本中测试我的项目。弹出的错误之一与不明确的运算符有关(with reversed parameter order)。这似乎没有在 C++17 中弹出。

例如:(https://godbolt.org/z/Gazbbo

我不确定为什么这会是一个问题。在我看来,这里唯一可行的功能是bool operator==(const B& other) constasA可以隐式转换为B但不能反过来。事实上,如果我用标记代替B(const A&)explicit我会得到一个B无法转换为A.

我试图了解我可以做些什么来避免这种情况,除了使用explicit或使用B(a). 想象一下AB如果是库代码,我如何在不破坏低版本界面的情况下支持 C++20?

0 投票
1 回答
120 浏览

c++ - MSVC 的标准库没有为 std::string、std::shared_ptr 等定义 spaceship 运算符?

我正在尝试使我的程序多平台,最初是为 Linux 编写的。MSVC(我使用的是 19.28)被告知从 19.20 版(https://en.cppreference.com/w/cpp/compiler_support/20)开始支持宇宙飞船操作员,但它似乎没有为 std 定义这个操作员::string 或 std::shared_ptr (可能适用于许多其他生物)。

我真正想做的是:

现场示例: https ://godbolt.org/z/Eo49hh

它在 GCC 10.2 下工作。我在这里遗漏了一些观点,还是没有完全支持?

0 投票
1 回答
92 浏览

c++ - 为什么 std::tuple 调用运算符 <=> 两次?

以下代码调用运算符 <=> 两次,参数颠倒。但为什么?

GCC 10.2 和 clang 12 似乎都在使用 libstdc++-10,其 <tuple> 确实提供了运算符 <=>,因此这似乎不是缺少标准库支持的情况,而且我的代码必须不正确。如何解决?

0 投票
1 回答
111 浏览

c++ - 为什么 spaceship 允许混合比较(不同的模板实例化)与无意义的结果?

编辑:这与宇宙飞船无关。只是使用 spaceship 混淆了我的代码中的真正问题(有关详细信息,请参阅答案)。

我对这个程序的输出感到惊讶:(如果您喜欢谜题,请随时打开 Godbolt 链接并尝试自己找出原因)

输出:




在指责了Godbolt缓存之后......我发现问题在于我正在比较TotallyOrdered<float>TotallyOrdered<double>(在给出预期输出f之后添加)。1234.567我的问题是:

  • 为什么允许这样做?(不问这是否是标准行为;它是,但对设计意图感到好奇。)
  • 为什么比较没有给出strong_ordering中的“枚举”?尽管我只定义了strong_order <=>.
  • 如何强制仅“精确 +-cvref”比较(给出std::strong_ordering结果)编译,防止给出的比较std::partial_ordering
0 投票
2 回答
126 浏览

c++ - 为什么 C++20 中的空结构没有隐式宇宙飞船运算符?

动机:有时我使用 std::variant 来实现“花式”枚举,其中一些枚举状态可以携带状态。

现在,如果我想<=>为我的变体使用它,它需要我的空结构已定义 <=>。这对我来说似乎有点奇怪,因为如果类型的状态位为 0,则该类型的所有实例都是相同的。

完整示例

0 投票
3 回答
2793 浏览

c++ - 使用 C++20 三向比较进行更静默的行为变化

令我惊讶的是,我遇到了另一个障碍,比如C++20 行为用相等运算符破坏现有代码?.

考虑一个简单的不区分大小写的键类型,与例如std::setor一起使用std::map

简单测试:


明显的解决方法

一个明显的解决方法是operator<=>在 C++20 模式下有条件地提供:编译资源管理器

问题

令我惊讶的是,我遇到了另一种破坏性更改的情况——C++20 在没有诊断的情况下更改了代码的行为。

在我阅读std::tuple::operator<它时应该有效:

3-6)按字典顺序比较lhs,即比较第一个元素,如果它们等价,则比较第二个元素,如果它们等价,则比较第三个元素,依此类推。对于非空元组,(3) 等价于rhsoperator<

我知道从技术上讲,这些从 C++20 开始就不再适用,它被替换为:

通过综合三向比较(见下文)按字典顺序进行比较lhsrhs即比较第一个元素,如果它们相等,比较第二个元素,如果它们相等,比较第三个元素,依此类推

和...一起

<、<=、>、>= 和 != 运算符分别由operator<=>和合成operator==(C++20 起)

事情是,

  • 我的类型没有定义operator<=>也不operator==

  • 并且正如这个答案所指出的那样,提供operator<额外的东西会很好,并且应该在评估简单的表达式时使用,比如a < b.

  1. C++20 中的行为更改是否正确/故意?
  2. 应该有诊断吗?
  3. 我们可以使用其他工具来发现像这样的无声破损吗?感觉就像扫描整个代码库以在tuple/中使用用户定义的类型pair并不能很好地扩展。
  4. tuple除了/之外,还有其他类型pair可以表现出类似的变化吗?