簡體   English   中英

關於使用位操作的位模式的建議

[英]Suggestion for a pattern involving bits using bit manipulation

我目前有這樣的結構

struct foo
{
  UINT64 optionA = 0;
  UINT64 optionB = 0;
  UINT64 optionC = 0;
}

我正在嘗試編寫一個 function 來比較foo基於optionAoptionBoptionC的兩個對象。 基本上我希望 function 做的是檢查optionA在兩者中是否相同,如果否,則返回最低的 object。 如果兩個對象中的optionA相同,則它將檢查兩個對象中的optionB並返回最低的一個。 如果optionB在兩者中相同,那么它將查看optionC並返回最低值。

我認為這可以通過為每個 object 分配一個 UINT64 no 來實現。 然后根據優先級分配位,然后比較每個位並返回較小的位。 我不確定如何 go 關於這種方法的任何建議將不勝感激。

該代碼目前缺少一個檢查相等性的運算符。

例子:

constexpr bool operator==(const foo& a, const foo& b) {
    return
        a.optionA == b.optionA &&
        a.optionB == b.optionB &&
        a.optionC == b.optionC;
}

這樣,以下將編譯(有意義地):

using UINT64 = /* unsigned long long */; // usually

struct foo {
    UINT64 optionA = 0;
    UINT64 optionB = 0;
    UINT64 optionC = 0;
};

constexpr bool operator==(const foo& a, const foo& b) {
    return
        a.optionA == b.optionA &&
        a.optionB == b.optionB &&
        a.optionC == b.optionC;
}

int main() {
    constexpr foo a, b;
    static_assert(a == b);
}

使用 C++20, 默認operator <=>operator ==可以完成這項工作。

struct foo
{
  UINT64 optionA = 0;
  UINT64 optionB = 0;
  UINT64 optionC = 0;

  auto operator <=>(const foo&) const = default;
  bool operator ==(const foo&) const = default;
};

否則, std::tuple可能會有所幫助:

bool operator ==(const foo& lhs, const foo& rhs)
{
   return std::tie(lhs.optionA, lhs.optionB, lhs.optionC)
       == std::tie(rhs.optionA, rhs.optionB, rhs.optionC);
}

bool operator <(const foo& lhs, const foo& rhs)
{
   return std::tie(lhs.optionA, lhs.optionB, lhs.optionC)
        < std::tie(rhs.optionA, rhs.optionB, rhs.optionC);
}

只進行比較 function 會更簡單,更易讀:

foo compare(foo x, foo y)
{
    // needs to hold status for 3 data members (one bit each)
    int x_status = 0, y_status = 0;

    // each bit is 1 if this member is bigger, 0 if smaller
    x_status |= (x.optionC > y.optionC)<<0;
    x_status |= (x.optionB > y.optionB)<<1;
    x_status |= (x.optionA > y.optionA)<<2;

    // each bit is 1 if this member is bigger, 0 if smaller
    y_status |= (x.optionC < y.optionC)<<0;
    y_status |= (x.optionB < y.optionB)<<1;
    y_status |= (x.optionA < y.optionA)<<2;

    // so now we can compare the values
    // if all the data members were bigger the value will be 7 (0b111)
    // if all the data members were smaller the value will be 0 (0b000)
    if (x_status < y_status) return x; else return y;
}

在這里在線試用: https://onlinegdb.com/XpdOSFLFa

暫無
暫無

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

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