gpt4 book ai didi

c++ - 为什么宇宙飞船允许混合比较(不同的模板实例)与无意义的结果?

转载 作者:行者123 更新时间:2023-12-03 16:31:42 25 4
gpt4 key购买 nike

编辑:这与飞船无关。只是飞船的使用混淆了我代码中的真正问题(详见答案)。
我对这个 program 的输出感到惊讶:
(如果您喜欢谜题,请随时打开 Godbolt 链接并尝试自己找出原因)

#include <cstdint>
#include <cassert>
#include <compare>
#include <cmath>
#include <iostream>
#include <limits>

template<typename T>
struct TotallyOrdered
{
T val;
constexpr TotallyOrdered(T val) :
val(val) {}
constexpr operator T() const { return val; }
constexpr std::strong_ordering operator<=>(TotallyOrdered const& other) const
{
if (std::isnan(val) && std::isnan(other.val))
{
return std::strong_ordering::equal;
}
if (std::isnan(val))
{
return std::strong_ordering::less;
}
if (std::isnan(other.val))
{
return std::strong_ordering::greater;
}
if (val < other.val)
{
return std::strong_ordering::less;
}
else if (val == other.val)
{
return std::strong_ordering::equal;
}
else
{
assert(val > other.val);
return std::strong_ordering::greater;
}
}
};



int main()
{
const auto qNan = std::numeric_limits<float>::quiet_NaN();
std::cout << std::boolalpha;
std::cout << ((TotallyOrdered{qNan} <=> TotallyOrdered{1234.567}) == std::strong_ordering::less) << std::endl;
std::cout << ((TotallyOrdered{qNan} <=> TotallyOrdered{1234.567}) == std::strong_ordering::equal) << std::endl;
std::cout << ((TotallyOrdered{qNan} <=> TotallyOrdered{1234.567}) == std::strong_ordering::equivalent) << std::endl;
std::cout << ((TotallyOrdered{qNan} <=> TotallyOrdered{1234.567}) == std::strong_ordering::greater) << std::endl;
}
输出:

false
false
false
false


在有点责备Godbolt缓存之后......我发现问题在于我正在比较 TotallyOrdered<float>TotallyOrdered<double> (在 f 之后添加 1234.567 给出预期输出)。
我的问题是:
  • 为什么这是允许的? (不是问这是否是标准行为;它是,但对设计意图感到好奇。)
  • 为什么比较在 strong_ordering 中没有给出任何“枚举”?虽然我只定义了 strong_order,但在进行混合比较时,我似乎得到了偏序。 <=> .
  • 我怎样才能强制只编译“精确 +-cvref”比较(给出 std::strong_ordering 结果),从而阻止给出 std::partial_ordering 的比较?
  • 最佳答案

    这是允许的,因为您的转换运算符为 T不明确。这允许比较的双方进行用户定义的转换到各自的 T .所以你最终得到一个 float和一个 double .然后这些都可以转换为 double并且可以进行比较。但该比较返回 std::partial_ordering ,不是 std::strong_ordering .
    请注意 std::strong_ordering 可以与 bool 进行比较,这就是您的代码首先编译的原因。尽管 cppreference.com 确实注意到:

    The behavior of a program that attempts to compare a strong_ordering with anything other than the integer literal ​0​ is undefined.


    我不能 100% 确定您的程序是否显示未定义的行为,或者是否有更多的转换/促销“魔法”正在进行。
    无论哪种方式,如果您将转换运算符更改为显式,代码将不再编译。我猜这就是你真正想要的?

    关于c++ - 为什么宇宙飞船允许混合比较(不同的模板实例)与无意义的结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66384530/

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