gpt4 book ai didi

c++ - 为非数组元素重载下标运算符

转载 作者:太空狗 更新时间:2023-10-29 20:27:55 25 4
gpt4 key购买 nike

我编写了一个模板类,用于将多个 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在标准库中。如 reference 中所述, std::vector<bool>它返回一个代理类,该类的运算符被重载以充当 vector 的元素。

你也可以。

有关用户友好的示例,请再次参阅 reference对于公共(public)接口(interface),它是这样的:

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();
};
// ...
};

要实现此类,您应该存储一个指向实际数据 block 的成员指针和一个用于操作的掩码。

举个真实的例子,在 g++ 头文件中寻找 std::vector<bool> 的成员类称为 std::vector<bool>::_Bit_reference在文件中bits/stl_bvector.h .


通过示例阐明 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);
}

关于c++ - 为非数组元素重载下标运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14807210/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com