使用位集适配器从operator []返回引用

问题描述

我正在使用带有枚举类的std :: bitset来拥有更方便的工具。但是当从operator []返回值时,我遇到了编译错误

error: non-const lvalue reference to type 'bool' cannot bind to a temporary of type 'std::__1::bitset<2>::reference' (aka '__bit_reference<std::__1::__bitset<1,2> >')

我必须通过引用将其返回,以便能够为其分配值。这是我的完整代码

template<typename T>
struct EnumTraits;

template<typename T>
class EnumClassBitset
{
private:
  std::bitset<static_cast<typename std::underlying_type<T>::type>(EnumTraits<T>::max)> m_bitset;

  typename std::underlying_type<T>::type get_value(T v) const
  {
    return static_cast<typename std::underlying_type<T>::type>(v);
  }

public:
  bool& operator[](T pos)
  {
    return m_bitset[get_value(pos)];
  }

  bool test(T pos) const
  {
    return m_bitset.test(get_value(pos));
  }

  EnumClassBitset& reset(T pos)
  {
    m_bitset.reset(get_value(pos));
    return *this;
  }

  EnumClassBitset& flip(T pos)
  {
    m_bitset.flip(get_value(pos));
    return *this;
  }
};

enum class BitFlags
{
    Write,Read,NumOfFlags
};

template<>
struct EnumTraits<BitFlags>
{
    static const BitFlags max = BitFlags::NumOfFlags;
};

这是我尝试使用的方式:

EnumClassBitset<BitFlags> m_flags;
m_flags[BitFlags::Write] = true;
cout << "Write flag: " << m_flags[BitFlags::Write] << endl;

感谢您的帮助,

解决方法

std::bitset(如std::vector<bool>)不会从bool &的非const版本返回operator[]。这样做的原因是技术性的,是由于bool变量只有一个字节,而std::bitset的元素只有一个字节。另外bool作为类型具有1字节的对齐要求,但std::bitset中的单个位未对齐。因此普通的bool &不能引用这样的元素。

这就是std::bitset::operator[]返回类型为std::bitset::reference的代理对象的原因。您可能必须转发这种类型,而不是返回bool &