尝试更改向量 bool 中的值
Trying to change a value in a vector bool
我正在阅读 Stroustrup PPP,在做练习时,我发现了这个错误。
为什么我不能更改向量 bool 的值?
#include "std_lib_facilities.h"
int main()
{
vector<bool> vecc(2, true);
vecc[1] = true; // I can't do this, returns error.
return 0;
}
错误:
error: cannot bind non-const lvalue reference of type 'bool&' to an rvalue of type 'bool' return std::vector<T>::operator[](i);
其次,当我尝试使用int类型时,问题没有出现。
#include "std_lib_facilities.h"
int main(){
vector<int> vecc = {true, true};
for(bool x : vecc) {cout<<x<<"\n";}
vecc[1] = false; //ok
for(bool x : vecc){cout<<x<<"\n";}
return 0;
}
输出:
1
1
1
0
编辑:
可能是因为我用的是#include "std_lib_facilities.h"
standard library 为 bool 类型提供了 std::vector 的特化,可以针对 space 效率进行优化。这将 bool 存储为 1 位,为大型向量节省了大量内存。
问题在于您不能 return 位的引用,因此标准库应该 return reference
对象包装器来允许赋值。该对象保留对向量的引用和您要求的位位置,并有一个 operator=()
调用 std::vector<bool>::assign()
.
这个示例代码甚至有这个:
std::vector<bool> is_prime(N, true);
is_prime[0] = is_prime[1] = false;
我唯一能想到的是你的编译器有一个旧版本的 STL 或者一个错误的实现,它有一个向量特化但没有包装器引用对象。尝试
vecc.assign(1, true);
std_lib_facilities.h 定义了以下帮助程序模板,以添加一些对开始编程生涯的人有帮助的错误检查:
// trivially range-checked vector (no iterator checking):
template< class T> struct Vector : public std::vector<T> {
using size_type = typename std::vector<T>::size_type;
/* #ifdef _MSC_VER
// microsoft doesn't yet support C++11 inheriting constructors
Vector() { }
explicit Vector(size_type n) :std::vector<T>(n) {}
Vector(size_type n, const T& v) :std::vector<T>(n, v) {}
template <class I>
Vector(I first, I last) : std::vector<T>(first, last) {}
Vector(initializer_list<T> list) : std::vector<T>(list) {}
*/
using std::vector<T>::vector; // inheriting constructor
T& operator[](unsigned int i) // rather than return at(i);
{
if (i<0 || this->size() <= i) throw Range_error(i);
return std::vector<T>::operator[](i);
}
const T& operator[](unsigned int i) const
{
if (i<0 || this->size() <= i) throw Range_error(i);
return std::vector<T>::operator[](i);
}
};
T& operator[](unsigned int i)
及其 const
变体 return 对 T
的引用,在这种情况下 T
是 bool
。要获取元素,它会调用 std::vector
的 operator[]
来完成繁重的工作。
不幸的是 std::vector<bool>
不是合适的库容器。因为它打包位而不是存储 bool
s,所以它不能 return 从元素访问方法中引用 bool
。它没有任何 bool
可供参考。 Instead it returns a groovy reference
class 将位封装从视线中隐藏起来,通常会让生活更轻松一些。在大多数情况下,元素访问方法的行为方式与常规 vector
.
完全相同
但这次不是。它不是 return 引用,也不是 return 对 bool
的引用,因此简单的 pass-through 无法编译。
常见的解决方法是使用包含一些小整数类型的 std::vector
或 enum
或使用 std::deque<bool>
,后者的使用方式大致相同但没有bit-backing 专业化。如果大小在编译时已知,请考虑使用 std::bitset
.
我正在阅读 Stroustrup PPP,在做练习时,我发现了这个错误。
为什么我不能更改向量 bool 的值?
#include "std_lib_facilities.h"
int main()
{
vector<bool> vecc(2, true);
vecc[1] = true; // I can't do this, returns error.
return 0;
}
错误:
error: cannot bind non-const lvalue reference of type 'bool&' to an rvalue of type 'bool' return std::vector<T>::operator[](i);
其次,当我尝试使用int类型时,问题没有出现。
#include "std_lib_facilities.h"
int main(){
vector<int> vecc = {true, true};
for(bool x : vecc) {cout<<x<<"\n";}
vecc[1] = false; //ok
for(bool x : vecc){cout<<x<<"\n";}
return 0;
}
输出:
1
1
1
0
编辑:
可能是因为我用的是#include "std_lib_facilities.h"
standard library 为 bool 类型提供了 std::vector 的特化,可以针对 space 效率进行优化。这将 bool 存储为 1 位,为大型向量节省了大量内存。
问题在于您不能 return 位的引用,因此标准库应该 return reference
对象包装器来允许赋值。该对象保留对向量的引用和您要求的位位置,并有一个 operator=()
调用 std::vector<bool>::assign()
.
这个示例代码甚至有这个:
std::vector<bool> is_prime(N, true);
is_prime[0] = is_prime[1] = false;
我唯一能想到的是你的编译器有一个旧版本的 STL 或者一个错误的实现,它有一个向量特化但没有包装器引用对象。尝试
vecc.assign(1, true);
std_lib_facilities.h 定义了以下帮助程序模板,以添加一些对开始编程生涯的人有帮助的错误检查:
// trivially range-checked vector (no iterator checking):
template< class T> struct Vector : public std::vector<T> {
using size_type = typename std::vector<T>::size_type;
/* #ifdef _MSC_VER
// microsoft doesn't yet support C++11 inheriting constructors
Vector() { }
explicit Vector(size_type n) :std::vector<T>(n) {}
Vector(size_type n, const T& v) :std::vector<T>(n, v) {}
template <class I>
Vector(I first, I last) : std::vector<T>(first, last) {}
Vector(initializer_list<T> list) : std::vector<T>(list) {}
*/
using std::vector<T>::vector; // inheriting constructor
T& operator[](unsigned int i) // rather than return at(i);
{
if (i<0 || this->size() <= i) throw Range_error(i);
return std::vector<T>::operator[](i);
}
const T& operator[](unsigned int i) const
{
if (i<0 || this->size() <= i) throw Range_error(i);
return std::vector<T>::operator[](i);
}
};
T& operator[](unsigned int i)
及其 const
变体 return 对 T
的引用,在这种情况下 T
是 bool
。要获取元素,它会调用 std::vector
的 operator[]
来完成繁重的工作。
不幸的是 std::vector<bool>
不是合适的库容器。因为它打包位而不是存储 bool
s,所以它不能 return 从元素访问方法中引用 bool
。它没有任何 bool
可供参考。 Instead it returns a groovy reference
class 将位封装从视线中隐藏起来,通常会让生活更轻松一些。在大多数情况下,元素访问方法的行为方式与常规 vector
.
但这次不是。它不是 return 引用,也不是 return 对 bool
的引用,因此简单的 pass-through 无法编译。
常见的解决方法是使用包含一些小整数类型的 std::vector
或 enum
或使用 std::deque<bool>
,后者的使用方式大致相同但没有bit-backing 专业化。如果大小在编译时已知,请考虑使用 std::bitset
.