[英]overwrite c++20 spaceship operator for enum class
我正在努力为枚举 class 提供新的宇宙飞船操作员。让我们举以下例子:
#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;
}
但很明显我在这里弄错了,因为我的main()
仍然告诉我,蚂蚁比老虎大。 如您所见,我试图显式删除默认的比较运算符,以强制编译器使用我的自定义太空船一号,但没有成功。
当我显式调用auto result = Animals::Ant <=> Animals::Tiger
时,我得到了ambiguous overload for 'operator<=>' (operand types are 'Animals' and 'Animals')
。 但这似乎与我的操作员签名有关(改为使用const
Animals)。
是否可以覆盖我的枚举的运算符(而不干扰其基本类型“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;
}
也就是说,在如何使用<=>
处理重写候选者方面存在实现分歧。 clang 和 msvc 实现了规则可能应该是什么,即我们的用户声明的operator<=>
抑制了所有内置的关系和三路 comaprison 运算符,以便Animals::Ant < Animals::Tiger
调用我们的operator<=>
。 但是 gcc 实现了规则在技术上实际上字面上所说的,即Animals::Ant <=> Animals::Tiger
评估我们的运算符,但使用<
不会。 有一个 gcc 错误报告为此打开 ( #105200 ),其中一位 gcc 开发人员指出了措辞问题。 这让我觉得这是一个措辞问题,而不是实际的设计意图问题,所以我要打开一个关于这个的核心问题 ( #205 )。
为了让它在 gcc 上工作,你还必须通过 go 并自己添加这些(注意:总是按值):
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;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.