在包含向量的<bool>类中重新定义运算符 []

Redefinition of operator [] in class that contains vector<bool>

本文关键字:定义 新定义 运算符 向量 包含 lt bool gt      更新时间:2023-10-16

我在将vector作为私有成员的类中重新定义运算符[]时遇到了问题。所以计划是有一个布尔向量,它将只包含true或false值。以下是您可以理解我遇到的问题的最小代码。

class A{
   private:
     std::vector<bool> _object;
   public:
   bool& operator[](size_t i) {return _object[i];};
   };

编译器错误为:对类型bool的非成本左值引用不能绑定到临时的"reference"(也称为"std::_Bit_reference")

我不明白在这种情况下,对象[I]怎么会是暂时的。

与其他std::vector<T>不同,std::vector<bool>::operator[]不返回T&(在本例中为bool&),而是一些实现定义的引用代理类,这些类不需要(在您的平台上也不)绑定到bool&。这是因为std::vector<bool>被允许是std::vector的空间有效专门化,而不是bool的天真数组。有关参考,请参阅此。

标准委员会普遍认为,这至少是一个糟糕的名字选择,因为它打破了人们在看std::vector时的合理期望。

不幸的是,对此没有惯用的解决方法。如果您想要正常的std::vector行为,您可能需要编写一个小的包装器类,或者只使用std::vector<char>。我意识到这两种情况都令人不快,我强烈认为引入专业化是一个错误。

如果可能,您可以使用boost::container::vector<bool>而不是std::vector<bool>。幸运的是,Boost没有重复那个不方便的错误,而是给这个节省空间的变体起了一个合适的名字。

这是因为只有对于std::vector<STL优化存储容量,使每个值都存储在一个位中。但是C++中对象的最小大小是sizeof(char)。因此,库需要构造对象,并且引用将是临时的。

好吧,你不能真正引用特定的位,而char是可寻址内存的最小单元。

std::vector<bool>的实现可能不同于参考文件的注释中提到的标准容器保证:

由于其表示可以被优化,std::vector<bool>不一定满足所有ContainerSequenceContainer的要求。例如,因为std::vector<bool>::iterator是实现定义的,所以它可能不满足ForwardIterator的要求。使用诸如std::search之类的需要ForwardIterators的算法可能导致编译时或运行时错误。