c++ 有没有更好的方法来获取指向std::vector元素的指针< bool>?

kcugc4gi  于 2024-01-09  发布在  其他
关注(0)|答案(1)|浏览(143)

我知道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>元素的指针:

  1. //Vector Bool Pointer - Helper class used for getting/setting bools put into vectors using pointers
  2. class VBP {
  3. public:
  4. VBP() {
  5. ptr = nullptr;
  6. mask = 0;
  7. }
  8. VBP(std::vector<bool>::reference ref) {
  9. /*
  10. std::vector<bool>::reference is the actual type returned when you index a
  11. std::vector<bool>, it just has an implicit cast to bool:
  12. constexpr operator bool() const noexcept {
  13. return (*_Getptr() & _Mask()) != 0;
  14. }
  15. constexpr const _Vbase* _Getptr() const noexcept {
  16. return this->_Myptr;
  17. }
  18. constexpr _Vbase _Mask() const noexcept {
  19. return static_cast<_Vbase>(1) << this->_Myoff;
  20. }
  21. Since we can pass references around, we can store from them the necessary information
  22. to effectively dereference them later.
  23. */
  24. ptr = (unsigned*)ref._Getptr();
  25. mask = static_cast<std::_Vbase>(1) << ref._Myoff; //I want to know whose idea it was to make
  26. //_Mask() a protected function but leave _Myoff public.
  27. }
  28. VBP& operator=(const VBP& other) {
  29. if (this != &other) {
  30. this->ptr = other.ptr;
  31. this->mask = other.mask;
  32. }
  33. return *this;
  34. }
  35. VBP& operator=(const bool& other) {
  36. if (ptr != nullptr && (bool)(*ptr & mask) != other) {
  37. *ptr ^= mask;
  38. }
  39. return *this;
  40. }
  41. bool operator==(const VBP& other) {
  42. return this->ptr == other.ptr && this->mask == other.mask;
  43. }
  44. bool operator==(const bool& other) {
  45. return ptr && (*ptr & mask) == other;
  46. }
  47. operator bool() {
  48. return ptr && *ptr & mask;
  49. }
  50. bool operator !() {
  51. return !ptr || !(*ptr & mask);
  52. }
  53. private:
  54. unsigned* ptr;
  55. std::_Vbase mask;
  56. };

字符串
这个类可以工作,我个人对它没有任何问题,但是我知道std::vector<bool>的工作方式是依赖于实现的,所以我不确定我在这里做的有多少在另一台机器上是可能的。例如,像_Myoff是公共的而_Mask()是受保护的,这似乎是一个奇怪的设计选择,我不能更普遍地依赖它。
有没有什么方法可以实现指向std::vector<bool>元素的指针,无论它是如何实现的?

2exbekwf

2exbekwf1#

std::vector<bool>::iterator的语义非常接近于指向bool的指针,包括通过间接向vector的元素分配新的bool值的能力。
下面是一个示例来说明这种方法:

  1. std::vector<bool> vb {true, true, false, false, true, false};
  2. std::cout << vb.size() << std::endl;
  3. for (size_t i = 0 ; i != vb.size() ; i++) {
  4. std::vector<bool>::iterator ptr = std::next(vb.begin(), i);
  5. std::cout << "before " << *ptr << " ";
  6. *ptr = !(*ptr);
  7. std::cout << "after " << *ptr << std::endl;
  8. }

字符串
通过*ptr的读取和通过*ptr = ...的写入都按预期工作。
Live demo.

相关问题