为啥析取赋值运算符 |= 不适用于布尔向量?
Posted
技术标签:
【中文标题】为啥析取赋值运算符 |= 不适用于布尔向量?【英文标题】:Why does the disjunction assignment operator |= not work with vectors of bools?为什么析取赋值运算符 |= 不适用于布尔向量? 【发布时间】:2018-03-14 11:29:21 【问题描述】:如果我有vector<bool> vec_bool
,那么我无法使用|=
赋值运算符修改向量的内容。也就是线条
vec_bool[0] |= true;
vec_bool[0] |= vec_bool[1];
给出编译错误,而行
bool a = false;
a |= true;
a |= vec_bool[0];
vec_bool[0] = vec_bool[0] | vec_bool[1];
vec_bool[0] = vec_bool[0] || vec_bool[1];
vector<int> vec_int(3);
vec_int[0] |= vec_int[1];
不要。这是什么原因?
(由 gcc)给出的错误是:
test.cpp:21:17: error: no match for ‘operator|=’(操作数类型是 ‘std::vector::reference aka std::_Bit_reference’ 和 ‘bool’)
【问题讨论】:
你必须记住std::vector<bool>
不是一个普通向量。它不是bool
的实际向量,而更像是位向量,C++ 规范未指定其实现。
Why does std::vector<bool> has no .data()?的可能重复
您可以查看en.cppreference.com/w/cpp/container/vector_bool了解更多信息
@GauravSehgal 相关,但不重复。相同的根本原因,但非常不同的问题/目标。
套用 Scott Meyers “vector<bool>
有两个问题。它不是向量。它不存储 bool
s”
【参考方案1】:
从std::vector<bool>
的operator[]
返回的reference
不是bool&
的别名,因为它是std::vector
的主要特化。它由C++ standard as this 指定:
// bit reference:
class reference
friend class vector;
reference() noexcept;
public:
~reference();
operator bool() const noexcept;
reference& operator=(const bool x) noexcept;
reference& operator=(const reference& x) noexcept;
void flip() noexcept; // flips the bit
;
如您所见,没有声明operator |=
。所以你不能将它应用到从vec_bool[0]
返回的引用上。
vec_bool[0] = vec_bool[0] | vec_bool[1];
起作用的原因是上面有 重载可以促进它。 operator bool()
将内置|
的两个操作数转换为bool
值。然后reference
的赋值运算符将结果赋值回vec_bool[0]
。
按照 C++ 标准的规定,std::vector<bool>
并不是一个特别好的抽象,IMO。
【讨论】:
谢谢!您能否告诉我vector<bool>
是否是唯一偏离向量类型的“标准”实现的向量类型?
@MeesdeVries - 这是 C++ 标准要求偏离主要声明的唯一一个。您可以假设的所有其他人都是主要模板。
...也就是说,其他人可能出于性能原因专门化,但您无法在可移植代码中检测到这一点。以上是关于为啥析取赋值运算符 |= 不适用于布尔向量?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 ~(true^true) 不正确?布尔运算符(否定)适用于“无符号字符”,但不适用于布尔值? (C++)