std::vector<bool> 的 SINGLE BIT 的按位运算。为什么会出错?
Bitwise operations on SINGLE BIT of std::vector<bool>. Why the error?
我想出了一套规则来将一组位转换为另一组位。
为了使这些工作正常,我基本上需要对源位集中的一定数量的位进行异或运算(例如,result[i]=source[foo(i)]^source[bar(i)]
,其中 foo
和 bar
是界限-检查)。由于我希望能够更改集合的大小,因此我决定使用 std::vector<bool>
.
因此,我最终得到:
int foo(int i);
int bar(int i);
void baz(std::vector<bool> in, std::vector<bool>& out){
out.clear();
for(int i=0;i<in.size();i++){
if(foo(i)>0 && foo(i)<in.size())
out[i]^=in[foo(i)]
if(bar(i)>0 && bar(i)<in.size())
out[i]^=in[bar(i)]
}
}
然而,这给了我一个错误:
No viable overloaded ^=
我该怎么做才能做到这些?
std::vector<bool>
在最好的情况下是混乱的,在最坏的情况下是可憎的。它的 operator[]
不是 return 一个 bool&
而是一个代理对象 (see here)。此代理没有重载所有可能的按位操作,因此您必须使用 ifs,它的 operator=(bool)
或它的 flip()
.
编辑:我只是阅读了您的代码,而不是您对您想做什么的描述。设置两位的异或完全没有问题:
out[i] = in[j] ^ in[k]; // Whatever the right indices are.
我认为你真正想做的是:
bool tmp = false;
if(foo(i)>0 && foo(i)<in.size())
tmp^=in[foo(i)];
if(bar(i)>0 && bar(i)<in.size())
out[i]=tmp^in[bar(i)];
即如果要returnin[bar(i)]^in[foo(i)]
如果都通过边界检查,returnin[j]
如果只有一个(这里表示为j
) 通过边界检查和 false
如果 none 他们通过它。
std::vector<bool>::operator[]
returns 一个代理 class。您可以在 cppreference.
上查看文档
您可以使用 static_cast<bool>
获取实际的 bool 值并在 XOR 中使用它。
out[i] = static_cast<bool>(out[i]) ^ in[foo(i)];
编辑: 或者正如 Max 所指出的,只需重写它就会进行隐式转换,因此强制转换是多余的。
out[i] = out[i] ^ in[foo(i)];
std::vector<bool>
is a special container. It's like a std::vector<int>
, but the standard allows for std::vector<bool>
to pack its elements into single bits which means it returns a proxy object 当你使用 operator[]
时。该对象没有 operator ^=
的重载,因此您不能使用它。你可以做的是写出 ^=
like
的长格式
out[i] = out[i] ^ in[foo(i)]
我想出了一套规则来将一组位转换为另一组位。
为了使这些工作正常,我基本上需要对源位集中的一定数量的位进行异或运算(例如,result[i]=source[foo(i)]^source[bar(i)]
,其中 foo
和 bar
是界限-检查)。由于我希望能够更改集合的大小,因此我决定使用 std::vector<bool>
.
因此,我最终得到:
int foo(int i);
int bar(int i);
void baz(std::vector<bool> in, std::vector<bool>& out){
out.clear();
for(int i=0;i<in.size();i++){
if(foo(i)>0 && foo(i)<in.size())
out[i]^=in[foo(i)]
if(bar(i)>0 && bar(i)<in.size())
out[i]^=in[bar(i)]
}
}
然而,这给了我一个错误:
No viable overloaded ^=
我该怎么做才能做到这些?
std::vector<bool>
在最好的情况下是混乱的,在最坏的情况下是可憎的。它的 operator[]
不是 return 一个 bool&
而是一个代理对象 (see here)。此代理没有重载所有可能的按位操作,因此您必须使用 ifs,它的 operator=(bool)
或它的 flip()
.
编辑:我只是阅读了您的代码,而不是您对您想做什么的描述。设置两位的异或完全没有问题:
out[i] = in[j] ^ in[k]; // Whatever the right indices are.
我认为你真正想做的是:
bool tmp = false;
if(foo(i)>0 && foo(i)<in.size())
tmp^=in[foo(i)];
if(bar(i)>0 && bar(i)<in.size())
out[i]=tmp^in[bar(i)];
即如果要returnin[bar(i)]^in[foo(i)]
如果都通过边界检查,returnin[j]
如果只有一个(这里表示为j
) 通过边界检查和 false
如果 none 他们通过它。
std::vector<bool>::operator[]
returns 一个代理 class。您可以在 cppreference.
您可以使用 static_cast<bool>
获取实际的 bool 值并在 XOR 中使用它。
out[i] = static_cast<bool>(out[i]) ^ in[foo(i)];
编辑: 或者正如 Max 所指出的,只需重写它就会进行隐式转换,因此强制转换是多余的。
out[i] = out[i] ^ in[foo(i)];
std::vector<bool>
is a special container. It's like a std::vector<int>
, but the standard allows for std::vector<bool>
to pack its elements into single bits which means it returns a proxy object 当你使用 operator[]
时。该对象没有 operator ^=
的重载,因此您不能使用它。你可以做的是写出 ^=
like
out[i] = out[i] ^ in[foo(i)]