簡體   English   中英

為非數組元素重載下標運算符

[英]Overloading subscript operator for non-array elements

我編寫了一個模板類,用於在整數中存儲多個bool。 現在,設置和獲取每個bool都是通過顯式函數完成的

    bool isBitSet(int index)
    {
        return static_cast<bool>((block_ >> index) % 2)
    }

    void setBitOn(int index)
    {
        block_ |= 1 << index;
    }

我相信以下內容對於獲取值是有效的,但是由於我們不能直接返回一點引用,因此如何設置工作?

    const bool operator [] (int index) const 
    {
        return static_cast<bool>((block_ >> index) % 2);
    }

std::vector<bool>和標准庫中的std::bitset中也是如此。 引用中所述, std::vector<bool>它返回一個代理類,該代理類將其運算符重載以充當向量的元素。

你也可以這樣做。

對於用戶友好的示例,請再次查看公共接口的參考 ,它是這樣的:

template <class Allocator>
class vector<bool, Allocator> {
  // ...
  public:
    class reference {
        friend class vector;
        reference();
      public:
        ~reference();
        operator bool() const;
        reference& operator=(bool x);
        reference& operator=(const reference&);
        void flip();
    };
  // ...
};

要實現此類,您應該存儲指向實際數據塊的成員指針和要操作的掩碼。

舉一個真實的例子,在g ++頭文件中,在文件bits/stl_bvector.h名為std::vector<bool>::_Bit_referencestd::vector<bool>成員類。


通過一個例子澄清OP:

假設你有一個包含320個bool的類。 你可以把它寫成:

class boolcontainer {
  uint32_t data[10];
public:
  //default ctor. to initialize the elements with zeros
  boolcontainer() { for (int i = 0; i < 10; ++i) { data[i] = 0; } }
}

您想要添加運算符[]。 添加一個const很容易:

class boolcontainer {
  uint32_t data[10];
public:
  bool operator[](int i) const { return data[i/32] & (1 << (i%32)); }
}

有一個非常數的你需要更多。 首先,您需要創建一個表示對您的值的引用的類。 你必須有一些指向存儲值的指針(在這種情況下)你需要一個位掩碼來指定一個具體的位。 為了能夠將其作為一個bool來處理,你需要添加一些運算符,即轉換為bool和operator =:

class reference {
  uint32_t *dataptr;
  uint32_t mask;
public:
  //constructor just initializing members
  reference(uint32_t *dataptr_, uint32_t mask_) : dataptr(dataptr_), mask(mask_) {}

  //conversion to bool
  operator bool() const {
    //just like in the getter, but the bitmask is stored now locally
    return *dataptr & mask;
  }

  //sets one single bit represented by mask to b
  reference& operator=(bool b) {
    if (b) {
      *dataptr |= mask;
    } else {
      *dataptr &= ~mask;
    }
    return *this;
  }

  //TODO copy ctor., operator==, operator<
};

請注意,上面的結構將表現為bool& - 讀取它從指針和掩碼表示的數據點讀取值,類似地,寫入它會覆蓋表示位置的位。 我還寫了一個初始化成員的構造函數。

現在你需要的是你的boolcontainer的operator []應該返回上面一個類的對象:

class boolcontainer {
  uint32_t data[10];
public:

  boolcontainer() { for (int i = 0; i < 10; ++i) { data[i] = 0; } }

  class reference {
     ... //see above
  }

  //keep the const version for efficiency
  bool operator[](int i) const { return data[i/32] & (1 << (i%32)); }

  //non-const version returns our reference object.
  reference operator[](int i) { return reference(&data[i/32], 1 << (i%32)); }
};

現在有一些代碼來測試它(只打印前40個值):

#include <iostream>
#include "boolcontainer.h"

void printboolcontainer(const boolcontainer &bc)
{
    //note that this is the constant version
    for (int i = 0; i < 40; ++i) {
        std::cout << bc[i];
    }
    std::cout << std::endl;
}

int main()
{
    boolcontainer bc;
    printboolcontainer(bc);
    bc[0] = true;
    bc[3] = true;
    bc[39] = true;
    printboolcontainer(bc);
}

暫無
暫無

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

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