[英]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_reference
的std::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.