gpt4 book ai didi

c++ - 为枚举类覆盖 C++20 宇宙飞船运算符

转载 作者:行者123 更新时间:2023-12-05 09:25:52 26 4
gpt4 key购买 nike

我正在努力为枚举类提供新的宇宙飞船操作符。让我们看下面的例子:

#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()仍然告诉我, Ant 比老虎大。如您所见,我试图显式删除默认的比较运算符,以强制编译器使用我的自定义 spaceship 一号,但没有成功。

当我显式调用 auto result = Animals::Ant <=> Animals::Tiger 时我得到一个 ambiguous overload for 'operator<=>' (operand types are 'Animals' and 'Animals') .但这似乎与我的运算符(operator)签名有关(改为使用 const Animals)。

是否可以覆盖我的枚举的运算符(而不干扰其基本类型“uint8_t”的运算符?

最佳答案

您的 operator<=> 有两个问题:

  1. 它需要按值获取枚举,而不是按常量引用,以抑制内置候选
  2. 它需要返回比较类别之一,而不是 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<=>抑制所有 内置关系和三向同胞运算符,因此Animals::Ant < Animals::Tiger调用我们的 operator<=> .但是 gcc 实现了规则在技术上实际上字面上所说的内容,即 Animals::Ant <=> Animals::Tiger评估我们的运营商,但使用 <才不是。为此打开了一个 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;
}

关于c++ - 为枚举类覆盖 C++20 宇宙飞船运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74964674/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com