循环范围和 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;
在后一种情况下,我得到一个错误
error: invalid initialization of non-const reference of type ‘std::_Bit_reference&’ from an rvalue of type ‘std::_Bit_iterator::reference {aka std::_Bit_reference}’
for(auto& i : boolVector)
vector<bool>
is (usually) specialized explicitly to store each bool
in a single bit,将存储成本从每个值一个字节减少到每八个值一个字节。据我所知,没有任何处理器是可位寻址的,因此不可能在 vector<bool>
中存储对值的引用。您需要使用纯 auto
,而不是 auto&
作为迭代值 i
。
因为std::vector<bool>
is not a container!
std::vector<T>
的迭代器通常取消对 T&
的引用,您可以将其绑定到您自己的 auto&
.
然而,std::vector<bool>
将其 bool
打包成整数,因此在访问它们时需要代理来进行位掩码。因此,它的迭代器 return a Proxy
.
并且由于 returned Proxy
是纯右值(临时),它不能绑定到左值引用,例如 auto&
.
解决方案:使用 auto&&
,如果给定一个左值引用,它将正确折叠成一个左值引用,或者如果给定一个代理,则绑定并保持临时存在。
std::vector<bool>
不遵守标准容器规则。
特别是,它的 operator[]
不 return bool&
。
无效代码中的循环
#include <vector>
#include <iostream>
int main() {
std::vector<bool> boolVector(10);
for (auto& i: boolVector)
std::cout << i;
}
可以通过以下三种方式中的任何一种来重写以遍历值:
(只读)
for (auto i: boolVector)
std::cout << i;
(只读,可能效率低下)
for (auto const& i: boolVector)
std::cout << i;
(read/write)
for (auto&& i: boolVector)
std::cout << i;
第一个和最后一个之间的选择取决于您是需要修改向量中的值,还是只需要读取它们。
为什么这段代码有效
std::vector<int> intVector(10);
for(auto& i : intVector)
std::cout << i;
这不是吗?
std::vector<bool> boolVector(10);
for(auto& i : boolVector)
std::cout << i;
在后一种情况下,我得到一个错误
error: invalid initialization of non-const reference of type ‘std::_Bit_reference&’ from an rvalue of type ‘std::_Bit_iterator::reference {aka std::_Bit_reference}’
for(auto& i : boolVector)
vector<bool>
is (usually) specialized explicitly to store each bool
in a single bit,将存储成本从每个值一个字节减少到每八个值一个字节。据我所知,没有任何处理器是可位寻址的,因此不可能在 vector<bool>
中存储对值的引用。您需要使用纯 auto
,而不是 auto&
作为迭代值 i
。
因为std::vector<bool>
is not a container!
std::vector<T>
的迭代器通常取消对 T&
的引用,您可以将其绑定到您自己的 auto&
.
std::vector<bool>
将其 bool
打包成整数,因此在访问它们时需要代理来进行位掩码。因此,它的迭代器 return a Proxy
.
并且由于 returned Proxy
是纯右值(临时),它不能绑定到左值引用,例如 auto&
.
解决方案:使用 auto&&
,如果给定一个左值引用,它将正确折叠成一个左值引用,或者如果给定一个代理,则绑定并保持临时存在。
std::vector<bool>
不遵守标准容器规则。
特别是,它的 operator[]
不 return bool&
。
无效代码中的循环
#include <vector>
#include <iostream>
int main() {
std::vector<bool> boolVector(10);
for (auto& i: boolVector)
std::cout << i;
}
可以通过以下三种方式中的任何一种来重写以遍历值:
(只读)
for (auto i: boolVector) std::cout << i;
(只读,可能效率低下)
for (auto const& i: boolVector) std::cout << i;
(read/write)
for (auto&& i: boolVector) std::cout << i;
第一个和最后一个之间的选择取决于您是需要修改向量中的值,还是只需要读取它们。