繁体   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