Search code examples
c++enumsoperator-overloadingc++17bitset

Return reference from operator[] using a bitset adapter


I am using std::bitset with enum class to have more convenient tool. But I am facing a compilation error when returning value from 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> >')

I have to return it via reference to be able to assign a value to it. Here is my full code:

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;
};

Here is how I am trying to use it:

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

Appreciate any help, thanks in advance.


Solution

  • std::bitset (like std::vector<bool>) does not return a bool & from the non-const-version of operator[]. The reasons for this are technical and come from the fact that a bool variable is one byte big while a element of std::bitset is only one bit big. Further bool as type has an alignment requirement of 1 byte, but the single bits in std::bitset are unaligned. So the normal bool & cannot reference to such an element.

    That's why the std::bitset::operator[] returns a proxy object of type std::bitset::reference. You probably have to forward this type instead of returning bool &.