[英]Strict weak ordering on pointer values
考慮以下結構:
struct Foo {
const Bar* x;
const Bar* y;
Foo(const Bar* _x, const Bar* _y = nullptr) : x(_x), y(_y) { assert(x); }
}
我們如何在x和y上定義嚴格的弱排序,以便可以在std :: set中使用該對象? 請注意,y可以是空指針。 正如在使用std :: less和nullptr中所提到的,未指定
未定義
std :: less on null指針的行為。 以下解決方案是否足夠?
bool operator<(const Foo& rhs) const {
uintptr_t numX = reinterpret_cast<uintptr_t>(x);
uintptr_t numY = reinterpret_cast<uintptr_t>(y);
uintptr_t numRhsX = reinterpret_cast<uintptr_t>(rhs.x);
uintptr_t numRhsY = reinterpret_cast<uintptr_t>(rhs.y);
return std::tie(numX, numY) < std::tie(numRhsX, numRhsY);
}
編輯:如果不是正確的方法(例如如何將std :: less與std :: tie結合起來)?
使用std::less<Bar*>
就足夠了(但是使用operator<
不是)。 std::less
的指針特化(作為“使用std :: less with nullptr”的接受答案指出)保證了總排序 。 與比較nullptr
是不確定的 ,這意味着該標准沒有強加特定排序,但std::less
仍然必須產生的總體排序(以及對於給定的指針p
, p < nullptr
必然產生相同的值每次)。
由於總排序強於弱排序,因此在您的情況下使用std::less
就足夠了。
編輯:如果不是正確的方法(例如如何將std :: less與std :: tie結合起來)?
不幸的是,沒有簡潔的方法。 由於std::tie
返回一個std::tuple
,並且元組上的比較是根據operator<
對它們的值(而不是std::less
)來定義的,所以你不能在這里使用std::tie
。 要使用std::less
,您必須手動執行:
bool operator<(const Foo& rhs) const {
if (std::less<>{}(x, rhs.x))
return true;
if (std::less<>{}(rhs.x, x))
return false;
return std::less<>{}(y, rhs.y);
}
順便說一句,你當前的實現(將指針重新解釋為整數)也會產生一個總排序(顯然,因為你要比較整數)但是你沒有未指定的行為,你將有實現定義的行為(來自reinterpret_cast
)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.