【发布时间】:2020-08-12 17:58:25
【问题描述】:
考虑这段代码:
#include <iostream>
#include <compare>
class A {
public:
int i = {};
std::strong_ordering operator<=> (A const& r) const
{
return i <=> r.i;
}
};
void TestA()
{
A a;
A b;
std::cout<< (a<b);
std::cout<< (a>b);
std::cout<< (a<=b);
std::cout<< (a>=b);
//std::cout<< (a==b); //ERROR
std::cout << 'E';
//std::cout<< (a!=b); //ERROR
std::cout << 'E';
std::cout<< std::is_eq(a<=>b);
std::cout<< std::is_neq(a<=>b) << std::endl;
}
class B {
public:
int i = {};
std::strong_ordering operator<=> (B const& r) const = default;
};
void TestB()
{
B a;
B b;
std::cout<< (a<b);
std::cout<< (a>b);
std::cout<< (a<=b);
std::cout<< (a>=b);
std::cout<< (a==b);
std::cout<< (a!=b);
std::cout<< std::is_eq(a<=>b);
std::cout<< std::is_neq(a<=>b) << std::endl;
}
class C {
public:
bool b = {};
int v1 = {};
int v2 = {};
std::strong_ordering operator<=> (C const& r) const
{
return (b?v1:v2) <=> (r.b?r.v1:r.v2);
}
bool operator== (C const& r) const
{
return std::is_eq(*this<=>r);
}
};
void TestC()
{
C a;
C b;
std::cout<< (a<b);
std::cout<< (a>b);
std::cout<< (a<=b);
std::cout<< (a>=b);
std::cout<< (a==b);
std::cout<< (a!=b);
std::cout<< std::is_eq(a<=>b);
std::cout<< std::is_neq(a<=>b) << std::endl;
}
int main()
{
TestA();
TestB();
TestC();
return 0;
}
https://wandbox.org/permlink/SLmLZOc18RaJV7Mu
删除 cmets 会出错。
首先我想问一下为什么默认的三通操作符与用户定义操作符的行为不同?
其次,这个问题的解决方案对于C 类是否正确,还是应该以不同的方式处理?
这只是一个简单的例子,我想到了更复杂的情况,有数十个字段和联合(如果你不明白我的意思,请查看一些英特尔 API ;))。
编辑:
这个问题Equality operator does not get defined for a custom spaceship operator implementation in C++20的重点是为什么用户定义的3路运算符没有默认的相等运算符,我想知道为什么默认和用户定义的行为有区别?
编辑 2:
我稍微修改了示例中的 C 类,以描绘更多现实生活中的问题(当默认运算符不是有效的解决方案时)。我还想澄清一下,我想知道这些差异背后的原因(用户定义和默认运算符之间),以便能够评估我的现实生活中的解决方案是否正确(类似于C),因为我确实重视更多的代码可维护性而不是我现在正在工作的部分代码的性能。
【问题讨论】:
-
我认为这是 Equality operator does not get defined for a custom spaceship operator implementation in C++20 的副本,除非你真的问“为什么这样做我得到一个默认的
==默认<=>?”,这似乎没有用。
标签: c++ operator-overloading c++20 spaceship-operator