我知道std::vector<bool>
是std::vector
的一个奇怪的特殊化,它的缺点之一是不可能获得指向单个元素的指针/引用。
我有一个情况,我需要指向元素的指针,使用std::deque<bool>
并不理想,因为额外的deref,std::vector<unsigned char>
也不理想,因为我正在使用std::any
s,除非我完全承诺永远不把我的bool称为bool,否则它会对我大喊大叫。
由于输入using Bool = unsigned char
对我来说太费力了,所以我决定创建一个helper类,它可以有效地作为指向std::vector<bool>
元素的指针:
//Vector Bool Pointer - Helper class used for getting/setting bools put into vectors using pointers
class VBP {
public:
VBP() {
ptr = nullptr;
mask = 0;
}
VBP(std::vector<bool>::reference ref) {
/*
std::vector<bool>::reference is the actual type returned when you index a
std::vector<bool>, it just has an implicit cast to bool:
constexpr operator bool() const noexcept {
return (*_Getptr() & _Mask()) != 0;
}
constexpr const _Vbase* _Getptr() const noexcept {
return this->_Myptr;
}
constexpr _Vbase _Mask() const noexcept {
return static_cast<_Vbase>(1) << this->_Myoff;
}
Since we can pass references around, we can store from them the necessary information
to effectively dereference them later.
*/
ptr = (unsigned*)ref._Getptr();
mask = static_cast<std::_Vbase>(1) << ref._Myoff; //I want to know whose idea it was to make
//_Mask() a protected function but leave _Myoff public.
}
VBP& operator=(const VBP& other) {
if (this != &other) {
this->ptr = other.ptr;
this->mask = other.mask;
}
return *this;
}
VBP& operator=(const bool& other) {
if (ptr != nullptr && (bool)(*ptr & mask) != other) {
*ptr ^= mask;
}
return *this;
}
bool operator==(const VBP& other) {
return this->ptr == other.ptr && this->mask == other.mask;
}
bool operator==(const bool& other) {
return ptr && (*ptr & mask) == other;
}
operator bool() {
return ptr && *ptr & mask;
}
bool operator !() {
return !ptr || !(*ptr & mask);
}
private:
unsigned* ptr;
std::_Vbase mask;
};
字符串
这个类可以工作,我个人对它没有任何问题,但是我知道std::vector<bool>
的工作方式是依赖于实现的,所以我不确定我在这里做的有多少在另一台机器上是可能的。例如,像_Myoff
是公共的而_Mask()
是受保护的,这似乎是一个奇怪的设计选择,我不能更普遍地依赖它。
有没有什么方法可以实现指向std::vector<bool>
元素的指针,无论它是如何实现的?
1条答案
按热度按时间2exbekwf1#
std::vector<bool>::iterator
的语义非常接近于指向bool
的指针,包括通过间接向vector的元素分配新的bool
值的能力。下面是一个示例来说明这种方法:
字符串
通过
*ptr
的读取和通过*ptr = ...
的写入都按预期工作。Live demo.