Tom*_*ken 2 c++ enums operator-overloading spaceship-operator c++20
我正在努力为枚举类提供新的宇宙飞船运算符。让我们看下面的例子:
#include <cstdio>
#include <iostream>
#include <compare>
#include <cstdint>
enum class Animals : uint8_t
{
Bird = 27, //those values are just for making a point
Tiger = 5,
Ant = 100,
Snake = 45,
Wale = 17
};
//auto operator<=(const Animals& lhs, const Animals& rhs) = delete;
//auto operator>=(const Animals& lhs, const Animals& rhs) = delete;
//auto operator<(const Animals& lhs, const Animals& rhs) = delete;
//auto operator>(const Animals& lhs, const Animals& rhs) = delete;
auto operator<=>(const Animals& lhs, const Animals& rhs)
{
std::cout << "comparing via overloaded <=> operator\n";
//order the animals by their size in real life
// Ant < Bird < Snake < Tiger < Wale
//for this MVCE only Ant < Tiger is in here:
if(lhs == Animals::Ant && rhs == Animals::Tiger)
return -1;
return 0; //all unimplemented ones are treated as equal
}
int main(void)
{
if(Animals::Ant < Animals::Tiger)
std::puts("success (do I see the prompt of the overloaded operator?)");
else
std::puts("seems to use uint8_t comparison instead");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但显然我在这里犯了一些错误,正如我的main()仍然告诉我的那样,蚂蚁比老虎更大。正如您所看到的,我尝试显式删除默认的比较运算符,以强制编译器使用我的自定义太空船一,但没有成功。
当我显式调用时,auto result = Animals::Ant <=> Animals::Tiger我得到一个ambiguous overload for 'operator<=>' (operand types are 'Animals' and 'Animals'). 但这似乎与我的操作员签名有关(使用const动物代替)。
是否可以覆盖我的枚举的运算符(而不干扰其基本类型“uint8_t”的运算符?
你的有两个问题operator<=>:
int. 在这种情况下可能std::weak_ordering是正确的。那是:
constexpr auto operator<=>(Animals lhs, Animals rhs) -> std::weak_ordering
{
//order the animals by their size in real life
// Ant < Bird < Snake < Tiger < Wale
//for this MVCE only Ant < Tiger is in here:
if(lhs == Animals::Ant && rhs == Animals::Tiger)
return std::weak_ordering::less;
return std::weak_ordering::equivalent;
}
Run Code Online (Sandbox Code Playgroud)
也就是说,如何处理重写候选者存在实现分歧<=>。clang 和 msvc 实现了可能应该的规则,即我们的用户声明operator<=>抑制所有内置的关系和三向比较运算符,以便Animals::Ant < Animals::Tiger调用我们的operator<=>. 但是 gcc 实现了技术上规则实际上字面上所说的内容,即Animals::Ant <=> Animals::Tiger评估我们的运算符,但 using<不评估。有一个为此开放的 gcc 错误报告 ( #105200 ),其中一位 gcc 开发人员指出了措辞问题。在我看来,这是一个措辞问题,而不是实际的设计意图问题,因此我将就此提出一个核心问题(#205)。
为了使其在 gcc 上工作,您还必须自己检查并添加这些内容(注意:始终按值):
constexpr auto operator<(Animals lhs, Animals rhs) -> bool {
return (lhs <=> rhs) < 0;
}
constexpr auto operator<=(Animals lhs, Animals rhs) -> bool {
return (lhs <=> rhs) <= 0;
}
constexpr auto operator>(Animals lhs, Animals rhs) -> bool {
return (lhs <=> rhs) > 0;
}
constexpr auto operator>=(Animals lhs, Animals rhs) -> bool {
return (lhs <=> rhs) >= 0;
}
Run Code Online (Sandbox Code Playgroud)