问题标签 [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 投票
1 回答
242 浏览

c++ - 将三路比较运算符的结果与 nullptr 进行比较有什么作用?

鉴于cppreference on<=>中的示例,我们可以将示例代码简化为:

但是我的 IDE(CLion 2020.2)通过 clang-tidy 警告说result != 0实际上应该是result != nullptr. 我不知道我们可以std::###_orderingnullptr. Cpprefence 还声称我们应该将它与 literal 进行比较0。那里什么都nullptr没有。

这段代码:

编译(GCC 10.1.0,Rev3,由 MSYS2 项目构建)并产生与版本相同的0结果nullptr


但是,我的 IDE 也警告我应该“ Clang-Tidy: Use nullptr ” with p1 < p2. 通过应用“修复”,代码会更改为std::cout << (p1 nullptr p2);无法编译的代码。它暗示它可能是 clang-tidy 中的一个错误,但它没有解释为什么我们可以将排序与nullptr. 为什么我们可以,为什么它有效,为什么我们想要它?

0 投票
1 回答
1026 浏览

c++ - 宇宙飞船操作员是否有 std::less/std::greater ?

所有基本比较 ( <, <=, ==, !=, >=, >) 都有一个关联的函数对象 ( std::less, std::less_equal, std::equal_to, std::not_equal_to, std::greater_equal, std::greater)。

飞船操作员<=>有类似的功能对象吗?如果没有,为什么没有添加到标准库中?

0 投票
3 回答
181 浏览

c++ - C++20:自动生成的运算符在派生类中不可引用?

在编写与宇宙飞船运算符相关的 C++20 时,我注意到一些相当奇怪的东西。

据我了解,从 C++20 开始,比较运算符是由编译器自动生成的。但是,我遇到了一个关于自动生成运算符的有趣问题。

在下面的代码中,我试图定义MyIterator哪个派生自vector<int>::iterator. 现在我希望基类受到保护并显式地公开函数。所以很自然地,我使用using声明来使用基类中的成员函数。但是,编译器抱怨operator!=缺少!

发生这种情况是因为自动生成的运算符“生成得太晚”吗?

有趣的是,定义中显示的解决方法MyIterator2似乎可以解决问题。

我想听听这种奇怪行为的原因。这是通过 spaceship 运算符自动生成的运算符的预期行为吗?或者这是编译器错误还是未实现的功能?

编译器版本信息:

代码(main.cpp):

补充笔记:

GCC 也以同样的方式拒绝代码。

0 投票
1 回答
252 浏览

c++ - 重写的比较运算符和表达式模板

我有一个受强烈影响的有限体积库,它可以像在纸上一样用 C++ 编写连续介质力学问题的解决方案。例如,要求解不可压缩层流的 Navier-Stokes 方程,我只需编写:

当然,这个表达式涉及表达式模板,因此系统系数是单程计算的,系统以无矩阵方式求解。

这些表达式模板基于 CRTP,因此所有必要的运算符都在基类中定义。特别是,相等运算符的定义如下:

whereSystemExpr<dim, rank, T<dim, rank, TRest...>, U<dim, rank, URest...>>具有懒惰地评估系数和计算解决方案的功能。

与 OpenFOAM 相比,在 OpenFOAM 中,您必须限定,例如,fvm::lapfvc::grad,以表明该术语将被显式或隐式评估,我采用了我在论文中一直使用的约定:左侧的所有内容都是隐式评估,而右侧是显式评估。因此,BaseExpr::operator ==不可交换。随着方程变长,这变得越来越有用。例如,可压缩流的 ε 输运方程为:

我担心在 C++20 下这个设计可能会因为operator ==. G++-10 编译库时没有任何警告,-std=c++20 -Wall -Wextra -pedantic但我想仔细检查一下:上面的代码在 C++20 下是否格式正确?

我知道有些人可能认为上面的设计很糟糕,但我喜欢它,以至于我宁愿保持-std=c++17模式而不是使用不同的运算符(比如,operator >>或其他)来表示相等(是的,那是平等的形式)。


使用 GCC-10.2,我得到了我想要的行为。考虑非定常传热方程:

最后一个示例无法编译完全没问题,因为它没有意义。我得到的错误是:

因此,即使在 C++20 模式下,GCC 的行为似乎也完全符合我的要求。


这是一个“最小”的例子:

0 投票
1 回答
680 浏览

c++ - 三路比较和 constexpr 函数模板:哪个编译器是对的?

考虑:

GCC 和 MSVC 接受T. Clang 拒绝它,并显示以下错误消息:

现场演示

如果 template-head ( template<class=void>) 被移除,或者如果f在声明之前显式或隐式实例化T,则 Clang 接受它。例如,Clang 接受:

现场演示

哪个编译器是正确的,为什么?

0 投票
3 回答
915 浏览

c++ - 顺序推导不一致的三向比较算子

前段时间我定义了我的第一个三路比较运算符。它比较了单一类型并替换了多个常规运算符。很棒的功能。然后我尝试实现一个类似的运算符来通过委托比较两个变体:

这不编译,我得到错误

自动返回类型的扣除不一致:'std::strong_ordering' 然后是 'std::partial_ordering'。

显然intdouble飞船操作员返回的类型不同。

解决这个问题的正确方法是什么?

0 投票
1 回答
227 浏览

c++ - 为什么 std::strong_ordering 有一个“等效”值?

的有效值为std::strong_orderinglessequal和。然而,看起来和是相等的(,可互换的),因为在这两种情况下,仅展示字段都等于零,并且没有其他状态可供仅展示构造函数初始化。equivalentgreaterstrong_ordering::equivalentstrong_ordering::equalvalue

strong_ordering没有任何单独 的值是有道理的equivalent,因为当排序很强时,等价的值总是相等的。但是,为 做strong_ordering::equivalent一个同义词strong_ordering::equal而不是根本不定义它有什么意义呢?

0 投票
2 回答
75 浏览

c++ - 使用非默认 <=> 生成 == 运算符

这个问题的轻微变化中。我想使用自定义运算符定义自定义类型,<=>并使用该自定义<=>运算符生成==. 尝试以下

我观察到默认==运算符不使用自定义<=>运算符,而是在没有任何自定义比较的情况下执行并比较所有数据成员。我可以自己定义一个==使用<=>如下的运算符,但我想知道是否有更好的方法来==摆脱<=>.

PS:编译器-资源管理器链接

PS:我知道自定义<=>不会生成默认值==,因为==它可能以比使用更优化的方式实现,<=>并且不希望生成低效的默认值。

0 投票
1 回答
116 浏览

c++ - 在编译时检查三向比较运算符支持

我想有条件operator <=>地在我的代码中启用重载,具体取决于是否支持给定当前版本的编译器及其命令行选项。例如,我希望将以下代码编译为 C++14、17 和 20(这本质上是我之前提出的问题的解决方案的续集):

所以,首先快速解释一下:

  • 隐式operator int是一个要求。
  • 比较运算符仅针对thing<int N>具有相同 的 s定义N
  • mismatched Ns 的运算符必须显式删除,否则编译器将决定隐式应用于operator int双方并使用int比较代替(请参阅链接问题)。
  • 预期的行为是第 40 行和第 43 行(标记)无法编译。

现在,我(认为)我需要有条件地检查operator <=>支持的原因是:

  • 代码需要编译为 C++14、17 和 20。
  • 如果我根本不重载<=>,则thing<0>() <=> thing<1>()错误地允许编译之类的东西(由于隐式转换为int; 与其他运算符的情况相同)。换句话说:默认operator <=>值并不是在所有情况下都合适,所以我不能任其发展。
  • 如果我总是编写这两个<=>重载,那么程序将无法编译为 C++14 和 C++17,或者可能无法在 C++20 实现不完整的编译器上编译(尽管我没有遇到过这种情况)。

只要我手动设置SPACESHIP_OPERATOR_IS_SUPPORTED,上面的代码就可以满足所有要求,但我希望它是自动的。

所以,我的问题是:有没有办法在编译时检测对 的支持operator <=>,并有条件地启用代码(如果存在)?还是有其他方法可以使 C++14 到 20 的工作?

我处于预编译器的心态,但如果有一些神奇的模板解决方案,那也可以。我真的很想要一个独立于编译器的解决方案,但至少我希望它可以在 GCC(5.x 及更高版本)和 MSVC(理想情况下为 2015 及更高版本)上工作。

0 投票
0 回答
51 浏览

c++ - 如何在 C++20 中编写自定义宇宙飞船运算符

我不明白为什么这段代码不能编译。根据一些网站,a == b应该重写为a.operator<=>(b) == 0,但是 clang 和 gcc 都无法编译。

但是,如果您使用默认值,一切正常!

所以我的问题是,你如何手动编写default实现<=>