问题标签 [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.
c++ - 将三路比较运算符的结果与 nullptr 进行比较有什么作用?
鉴于cppreference on<=>
中的示例,我们可以将示例代码简化为:
但是我的 IDE(CLion 2020.2)通过 clang-tidy 警告说result != 0
实际上应该是result != nullptr
. 我不知道我们可以std::###_ordering
与nullptr
. 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
. 为什么我们可以,为什么它有效,为什么我们想要它?
c++ - 宇宙飞船操作员是否有 std::less/std::greater ?
所有基本比较 ( <
, <=
, ==
, !=
, >=
, >
) 都有一个关联的函数对象 ( std::less
, std::less_equal
, std::equal_to
, std::not_equal_to
, std::greater_equal
, std::greater
)。
飞船操作员<=>
有类似的功能对象吗?如果没有,为什么没有添加到标准库中?
c++ - C++20:自动生成的运算符在派生类中不可引用?
在编写与宇宙飞船运算符相关的 C++20 时,我注意到一些相当奇怪的东西。
据我了解,从 C++20 开始,比较运算符是由编译器自动生成的。但是,我遇到了一个关于自动生成运算符的有趣问题。
在下面的代码中,我试图定义MyIterator
哪个派生自vector<int>::iterator
. 现在我希望基类受到保护并显式地公开函数。所以很自然地,我使用using
声明来使用基类中的成员函数。但是,编译器抱怨operator!=
缺少!
发生这种情况是因为自动生成的运算符“生成得太晚”吗?
有趣的是,定义中显示的解决方法MyIterator2
似乎可以解决问题。
我想听听这种奇怪行为的原因。这是通过 spaceship 运算符自动生成的运算符的预期行为吗?或者这是编译器错误还是未实现的功能?
编译器版本信息:
代码(main.cpp):
补充笔记:
GCC 也以同样的方式拒绝代码。
c++ - 重写的比较运算符和表达式模板
我有一个受openfoam强烈影响的有限体积库,它可以像在纸上一样用 C++ 编写连续介质力学问题的解决方案。例如,要求解不可压缩层流的 Navier-Stokes 方程,我只需编写:
当然,这个表达式涉及表达式模板,因此系统系数是单程计算的,系统以无矩阵方式求解。
这些表达式模板基于 CRTP,因此所有必要的运算符都在基类中定义。特别是,相等运算符的定义如下:
whereSystemExpr<dim, rank, T<dim, rank, TRest...>, U<dim, rank, URest...>>
具有懒惰地评估系数和计算解决方案的功能。
与 OpenFOAM 相比,在 OpenFOAM 中,您必须限定,例如,fvm::lap
等fvc::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 的行为似乎也完全符合我的要求。
这是一个“最小”的例子:
c++ - 顺序推导不一致的三向比较算子
前段时间我定义了我的第一个三路比较运算符。它比较了单一类型并替换了多个常规运算符。很棒的功能。然后我尝试实现一个类似的运算符来通过委托比较两个变体:
这不编译,我得到错误
自动返回类型的扣除不一致:'std::strong_ordering' 然后是 'std::partial_ordering'。
显然int
和double
飞船操作员返回的类型不同。
解决这个问题的正确方法是什么?
c++ - 为什么 std::strong_ordering 有一个“等效”值?
的有效值为std::strong_ordering
、less
、equal
和。然而,看起来和是相等的(即,可互换的),因为在这两种情况下,仅展示字段都等于零,并且没有其他状态可供仅展示构造函数初始化。equivalent
greater
strong_ordering::equivalent
strong_ordering::equal
value
strong_ordering
没有任何单独 的值是有道理的equivalent
,因为当排序很强时,等价的值总是相等的。但是,为 做strong_ordering::equivalent
一个同义词strong_ordering::equal
而不是根本不定义它有什么意义呢?
c++ - 使用非默认 <=> 生成 == 运算符
在这个问题的轻微变化中。我想使用自定义运算符定义自定义类型,<=>
并使用该自定义<=>
运算符生成==
. 尝试以下
我观察到默认==
运算符不使用自定义<=>
运算符,而是在没有任何自定义比较的情况下执行并比较所有数据成员。我可以自己定义一个==
使用<=>
如下的运算符,但我想知道是否有更好的方法来==
摆脱<=>
.
PS:编译器-资源管理器链接
PS:我知道自定义<=>
不会生成默认值==
,因为==
它可能以比使用更优化的方式实现,<=>
并且不希望生成低效的默认值。
c++ - 在编译时检查三向比较运算符支持
我想有条件operator <=>
地在我的代码中启用重载,具体取决于是否支持给定当前版本的编译器及其命令行选项。例如,我希望将以下代码编译为 C++14、17 和 20(这本质上是我之前提出的问题的解决方案的续集):
所以,首先快速解释一下:
- 隐式
operator int
是一个要求。 - 比较运算符仅针对
thing<int N>
具有相同 的 s定义N
。 - mismatched
N
s 的运算符必须显式删除,否则编译器将决定隐式应用于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 及更高版本)上工作。
c++ - 如何在 C++20 中编写自定义宇宙飞船运算符
我不明白为什么这段代码不能编译。根据一些网站,a == b
应该重写为a.operator<=>(b) == 0
,但是 clang 和 gcc 都无法编译。
但是,如果您使用默认值,一切正常!
所以我的问题是,你如何手动编写default
实现<=>
?