C++ 使用位集适配器从运算符[]返回引用

C++ 使用位集适配器从运算符[]返回引用,c++,enums,operator-overloading,c++17,bitset,C++,Enums,Operator Overloading,C++17,Bitset,我将std::bitset与enum类一起使用,以获得更方便的工具。但从运算符[]返回值时,我面临编译错误: 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> >') 错误:对类型“b

我将std::bitset与enum类一起使用,以获得更方便的工具。但从运算符[]返回值时,我面临编译错误:

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> >')
错误:对类型“bool”的非常量左值引用无法绑定到类型为“std::\uu 1::bitset::reference”(又名“\uu bit\u reference”)的临时
我必须通过引用返回它,才能给它赋值。这是我的全部代码:

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;
};
模板
结构特征;
模板
类枚举类位集
{
私人:
std::位集m_位集;
typename std::基础类型::类型获取值(tV)常量
{
返回静态_-cast(v);
}
公众:
bool和操作员[](T位置)
{
返回m_位集[get_value(pos)];
}
布尔测试(T位置)常数
{
返回m_位集测试(获取值(pos));
}
EnumClassBitset和reset(T位置)
{
m_bitset.reset(获取_值(pos));
归还*这个;
}
EnumClassBitset和flip(T位置)
{
m_bitset.flip(获取_值(pos));
归还*这个;
}
};
枚举类位标志
{
写
阅读
努莫夫旗
};
模板
结构枚举特征
{
静态常量BitFlags max=BitFlags::NumOfFlags;
};
以下是我尝试使用它的方式:

EnumClassBitset<BitFlags> m_flags;
m_flags[BitFlags::Write] = true;
cout << "Write flag: " << m_flags[BitFlags::Write] << endl;
EnumClassBitset m_标志;
m_标志[BitFlags::Write]=true;
cout
std::bitset
(如
std::vector
)不会从非
const
版本的
运算符[]
返回
bool&
。产生这种情况的原因是技术性的,并且来自这样一个事实,即
bool
变量是一个字节大,而
std::bitset
的元素只有一个字节大。此外,
bool
as类型的对齐要求为1字节,但
std::bitset
中的单个位未对齐。因此正常的
bool&
不能引用这样的元素

这就是返回类型为
std::bitset::reference
的代理对象的原因。您可能必须转发此类型,而不是返回
bool&
std::bitset
(如
std::vector
)而不是从非
const
版本的
运算符[]
返回
bool&
。产生这种情况的原因是技术性的,并且来自这样一个事实,即
bool
变量是一个字节大,而
std::bitset
的元素只有一个字节大。此外,
bool
as类型的对齐要求为1字节,但
std::bitset
中的单个位未对齐。因此正常的
bool&
不能引用这样的元素

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