以下代碼旨在對包含陣列的物件實作比較。兩個物件應該比較,就<,==,>好像所有陣列元素都這樣比較。由于各種原因,以下內容無法編譯:
#include <compare>
class witharray {
private:
array<int,4> the_array;
public:
witharray( array<int,4> v )
: the_array(v) {};
int size() { return the_array.size(); };
auto operator<=>( const witharray& other ) const {
array< std::strong_ordering,4 > cmps;
for (int id=0; id<4; id )
cmps[id] = the_array[id]<=>other.the_array[id];
return accumulate
(cmps.begin(),cmps.end(),
std::equal,
[] (auto x,auto y) -> std::strong_ordering { return x and y; }
);
};
};
首先,比較陣列:
call to implicitly-deleted default constructor of 'array<std::strong_ordering, 4>
然后嘗試累積比較:
no matching function for call to 'accumulate'
編譯器資源管理器:https ://godbolt.org/z/E3ovh5qGa
還是我完全走錯了路?
uj5u.com熱心網友回復:
如果所有陣列元素都這樣比較,兩個物件應該比較為
<, 。==>
這是一個相當有趣的命令。這里要注意的一件事是它是一個偏序。也就是說,給定{1, 2}vs {2, 1},這些元素不是全部 <or==或>。所以你留下了無序的。
C 20 的比較確實有一種方式來表示:你必須回傳一個std::partial_ordering.
我們可以實作這種排序的方式是我們首先比較第一個元素,然后我們確保所有其他元素比較相同。如果任何一對元素的比較不同,那么我們就知道我們是無序的:
auto operator<=>( const witharray& other ) const
-> std::partial_ordering
{
std::strong_ordering c = the_array[0] <=> other.the_array[0];
for (int i = 1; i < 4; i) {
if ((the_array[i] <=> other.the_array[i]) != c) {
return std::partial_ordering::unordered;
}
}
return c;
}
這樣做的好處是不必比較每一對元素,因為當我們到達第二個元素時,我們可能已經知道答案(例如{1, 2, x, x}vs {1, 3, x, x}is already unordered,與其他元素無關)。
這似乎是你試圖用你的 來完成的accumulate,除了accumulate這里的演算法是錯誤的,因為我們想早點停止。all_of在這種情況下,您需要:
auto comparisons = views::iota(0, 4)
| views::transform([&](int i){
return the_array[i] <=> other.the_array[i];
});
bool all_match = ranges::all_of(comparisons | drop(1), [&](std::strong_ordering c){
return c == comparisons[0];
});
return all_match ? comparisons[0] : std::partial_ordering::unordered;
誠然,這很尷尬。在 C 23 中,我們可以comparisons更直接地做這部分:
auto comparisons = views::zip_transform(
compare_three_way{}, the_array, other.the_array);
如果你有這樣的謂詞,它會更好讀:
bool all_match = ranges::all_of(comparisons | drop(1), equals(comparisons[0]));
或者為這個特定的用例撰寫自己的演算法(這是一個非常容易撰寫的演算法):
return all_same_value(comparisons)
? comparisons[0]
: std::partial_ordering::unordered;
uj5u.com熱心網友回復:
請注意,std::array已經有 spaceship 運算子,顯然可以滿足您的需要:
class witharray {
private:
array<int, 4> the_array;
public:
witharray(array<int, 4> v)
: the_array(v) {};
int size() { return the_array.size(); };
auto operator<=>(const witharray& other) const
{
return the_array <=> other.the_array;
};
};
https://godbolt.org/z/4drddWa8G
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/493782.html
下一篇:Raylib我的螢屏碰撞不準確
