Range-for-loops 和 std::vector<bool>
Range-for-loops and std::vector<bool>
为什么这个代码能在中工作
std::vector<int> intVector(10);
for(auto& i : intVector)
std::cout << i;
这不是吗?
std::vector<bool> boolVector(10);
for(auto& i : boolVector)
std::cout << i;
在后一种情况下,我得到一个错误
错误:类型为"std::_Bit_reference&"的非常量引用的初始化无效来自类型为"std::_Bit_iterator::reference{aka std::_Bit_reference}"的右值
for(auto& i : boolVector)
因为std::vector<bool>
不是容器!
std::vector<T>
的迭代器通常取消对T&
的引用,您可以将其绑定到自己的auto&
。
然而,std::vector<bool>
将其bool
封装在整数中,因此在访问它们时需要一个代理来进行位屏蔽。因此,它的迭代器返回一个Proxy
由于返回的Proxy
是一个prvalue(临时),因此它无法绑定到诸如auto&
之类的左值引用。
解决方案:使用auto&&
,如果给它一个左值引用,它将正确地折叠成左值引用;或者,如果给了它一个代理,它将绑定并保持临时活动。
std::vector<bool>
不遵守标准容器规则。
特别地,它的迭代器的operator*
不返回bool&
。
无效代码中的循环
#include <vector>
#include <iostream>
int main() {
std::vector<bool> boolVector(10);
for (auto& i: boolVector)
std::cout << i;
}
可以通过以下三种方式中的任何一种重写以迭代值:
(只读)
for (auto const i: boolVector) std::cout << i;
(只读,可能效率低下)
for (auto const& i: boolVector) std::cout << i;
(读/写²)
for (auto&& i: boolVector) std::cout << i;
在第一个和最后一个之间的选择取决于您是需要修改向量中的值,还是只读取它们。
注:
我说"可能效率低";因为它具有不必要的间接性。任何优秀的优化器都应该创建与第一个示例相同的代码。
for (auto i: boolVector)
还提供了向量的读/写视图(因为我们已经复制了代理对象)。但我不建议这样做,因为读者可能会认为这样的写作只会产生局部效果,就像标准容器一样。这就是为什么我在只读情况下使用
auto const i
;或者,我们可以使用boolVector | std::views::as_const
(由于C++23)或通过使用对向量的const引用(for (auto const& v = boolVector; auto i: v)
)来获得const的代理。
vector<bool>
(通常)专门用于将每个bool
存储在一个位中,从而将存储成本从每个值一个字节降低到每八个值一个比特。据我所知,目前没有一个处理器是位可寻址的,因此不可能在vector<bool>
中存储对值的引用。迭代值i
需要使用普通的auto
,而不是auto&
。
- 写入向量<向量<bool>>
- EASTL矢量<向量<int>>连续的
- 让bool方法返回其他整数
- 如何在 std::vector 中找到<bool>哪些索引是真的?
- Arduino-C++ bool 不会从 false 变为 true
- 为什么在这种情况下,bool 类型的输出等于 0?
- 显式 std::exception_ptr 转换为 bool 不存在.VS2010 错误?
- 错误:不能使用"显式"说明符声明 bool'
- 为什么 C++ 11 在 ios 类中添加了运算符 bool
- 从标准::字符串到标准::矢量<bool>的快速转换
- 为什么 bool 和 _Bool 如果它们在内存中占用 1 个字节,它们只能存储 0 或 1
- 通过 mpi 发送 c++ 标准::矢量<bool>
- 为什么使用Pool和Bool而不是int8_t或char
- 如何为地图< map<int,int> 、bool > 分配值?
- 为什么更改包含 psapi.h 的顺序会产生编译错误?(标识符 BOOL 未定义)
- 使用 bool 和 const char 重载的 C++ 函数会在没有警告的情况下产生歧义 (MSVC2012)
- 返回 bool 作为 CPP 中 bool 运算符 [] 中的值
- 如何告诉自动推断向量<bool>元素的非引用类型
- 当 Type = bool 时,运算符 bool() 与模板 Type() 运算符冲突
- 为什么"std::set::erase(const key_type&)"返回"size_type"而不是"bool"?