簡體   English   中英

比較運算符與三向運算符的嵌套生成?

[英]Nested generation of comparison operator with three-way operator?

考慮S的以下兩個重載operator<=>

#include <compare>

struct S {};

int operator<=>(S, int) { return 0;  } #1
S   operator<=>(S,   S) { return {}; } #2

如果我將object Sint進行比較, #1將為我生成正確的運算符,因此像S{} <= 00 < S{}0 <=> S{}這樣的表達式就可以了。

但是,如果我將 object S與其他 object S進行比較:

S{} < S{};

然后這將被重寫為(S{} <=> S{}) < 0 由於(S{} <=> S{})將返回另一個S ,我們回到原點問題: Sint進行比較。 目前,我們沒有operator<(S, int) ,所以#1會為我生成正確的運算符。

但令人驚訝的是,三個編譯器都沒有對我這樣做。 GCC、Clang 和 MSVC拒絕S{} < S{}並顯示相同的錯誤消息:

no match for 'operator<' (operand types are 'S' and 'int')

這讓我很沮喪。 因為#1確實存在。 為什么這里沒有發生操作符的嵌套生成? 標准是怎么說的? 是否存在 static 約束違規?

這是格式錯誤的,盡管錯誤消息確實令人困惑。

來自[over.match.oper]/8的規則是(強調我的):

如果通過重載決策為運算符@選擇了重寫的operator<=>候選者,如果所選候選者是具有相反參數順序的合成候選者,則x @ y被解釋為0 @ (y <=> x) ,或者(x <=> y) @ 0否則,使用選定的重寫operator<=>候選。 在結果表達式的上下文中不考慮運算符@的重寫候選。

表達式S{} < S{}將解析為重寫后的候選(S{} <=> S{}) < 0 生成的表達式在其查找中不會考慮重寫的候選者。 因此,當我們執行S{} < 0時,將查找operator< ,而不是operator<=> 它找不到這樣的東西,所以表達式是不正確的。

<source>:8:14: error: no match for 'operator<' (operand types are 'S' and 'int')
    8 | auto x = S{} < S{};
      |          ~~~~^~~~~

從這個意義上說,錯誤是真的:沒有匹配,特別是operator<與這些操作數。 雖然如果錯誤消息有更多的上下文來解釋它為什么要尋找它(並且我在99629中提交了一個請求),這會有所幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM