如何在 C++ 中实现位数组

How to implement an array of bits in C++

我正在尝试编写一个包含位数组(作为成员变量)的 C++ 模板 class。位数组的大小在编译时是已知的,所以我真的很希望它是一个 std::bitset,但是我很难将 operator[] 函数写入 set 位。

例如,我希望我的 class 像这样开始:

template<size_t N>
class bitvector
{
public:
    bool operator[](size_t i) const { return bits[i]; }
    bool& operator[](size_t i) { return bits[i]; }
private:
    std::bitset<N> bits;
};

getter 工作正常。问题是 std::bitset::operator[] setter 函数 returns 一个 std::bitset::reference (不是 bool&),它本身是模板化的。我对模板不太熟悉,但以下尝试失败了:

template<size_t K>
std::bitset<K>::reference operator[](size_t i) { return bits[i]; }

出现以下错误 need 'typename' before 'std::bitset<K>::reference' because 'std::bitset<K>' is a dependent scope。我尝试了一些谷歌搜索,但无济于事。

std::bitset 是适合这项任务的工具吗?如果是这样,我该如何编写 setter 函数?如果没有,我可以用什么代替? (我仍然希望它实际存储为位,并且 std::vector<bool> 似乎不太正确,因为我希望数组大小在编译时严格固定)。

您可以 return 一个 std::bitset<N>::reference 如下:

template<size_t N>
class bitvector
{
public:
    bool operator[](size_t i) const { return bits[i]; }
    typename std::bitset<N>::reference operator[](size_t i) { return bits[i]; }
private:
    std::bitset<N> bits;
};

不需要额外的 template<size_t K>,因为您仍然可以访问原始模板参数 N,并且在任何情况下您都不希望 N 和 K 不同。

您需要在函数的 return 类型之前加上 typename 来告诉编译器 ::reference 是一个类型而不是一个值。

例如:

struct Foo{
   typedef int reference;
};

struct Bar{
    static int reference;
};

这里 Foo::reference 是一个类型,但是 Bar::reference 是一个变量,在 return 类型之前没有 typename 编译器会报错,因为它可能是 std::bitset<N>::reference 是一个变量。 (编译器应该拥有计算出它不是一个值所需的所有信息,但出于某种原因它仍然是必需的)。