默认的三向比较生成的代码比预期多

问题描述 投票:0回答:1

考虑以下代码:

struct B {
    friend bool operator< (const B&, const B&);
    friend bool operator==(const B&, const B&);
};

struct D : B {
    friend std::strong_ordering operator<=>(const D&, const D&) = default;
};

bool less(const D& a, const D& b) {
    return a < b;
}

运算符

<
==
故意未定义,以避免与其内联相关的优化。

当我查看 less()

 函数的汇编代码
(gcc)时,它似乎完全等同于以下内容(对于
std::strong_ordering
std::weak_ordering
的返回类型都是如此):
operator<=>

而我期待看到这个:

bool less(const D& a, const D& b) { if (static_cast<const B&>(a) == static_cast<const B&>(b)) return false; else return static_cast<const B&>(a) < static_cast<const B&>(b); }

为什么编译器会生成对 
bool less(const D& a, const D& b) { return static_cast<const B&>(a) < static_cast<const B&>(b); }

的额外调用,而不是仅仅调用

operator==(const B&, const B&)
?是缺少优化还是有检查相等性的根本原因?
    

c++ c++20 spaceship-operator
1个回答
0
投票
operator<(const B&, const B&)

的结果。

如果我对你的代码片段有这个功能:

<=>

您会看到

std::strong_ordering compare(const D& a, const D& b){ return a <=> b; } 的行为是首先检查是否相等,如果失败则进行比较(强制词法排序的合理实现)。

然后根据

cppreference

其他默认比较运算符 四个关系运算符中的任何一个都可以显式默认。默认关系运算符必须具有返回类型 bool。

如果 x
y 上的重载解析(还考虑参数相反顺序的运算符
)失败,或者如果此运算符@不适用于该 x <=> y 的结果,则将删除此类运算符。 <=>否则,如果重载决议选择了具有原始参数顺序的运算符<=>,则默认的operator@调用x y @ 0,否则调用0 @ y <=> x:<=><=>

(强调我的)。

所以,你的

<=>

函数调用

less
实际上是在调用
a < b
,没有函数和结构体,不可能变得更智能和优化。
    

© www.soinside.com 2019 - 2024. All rights reserved.