1

我提出了一套规则来将一组位转换为另一组。

为了使这些工作,我基本上需要对源位集中的一定数量的位进行异或运算(例如,result[i]=source[foo(i)]^source[bar(i)]在哪里foobar被边界检查)。由于我希望能够更改集合的大小,因此我决定使用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)]
   }
}

但是,这给了我一个错误:

没有可行的重载^=

为了能够做这些事情,我能做些什么?

4

3 回答 3

4

std::vector<bool>在最好的情况下是混乱的,在最坏的情况下是可憎的。它operator[]不返回一个bool&而是一个代理对象(见这里)。此代理没有重载所有可能的按位操作,因此您必须使用 ifs、itsoperator=(bool)或 its 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)];

也就是说,如果您想in[bar(i)]^in[foo(i)]在两者都通过边界检查时返回,in[j]则在只有一个(这里用 表示j)通过边界检查并且false没有一个通过边界检查时返回。

于 2020-01-15T16:58:21.350 回答
2

std::vector<bool>是一个特殊的容器。它就像 a std::vector<int>,但标准允许std::vector<bool>将其元素打包成单个位,这意味着它在您使用时返回一个代理对象operator[]. 该对象没有重载,operator ^=因此您无法使用它。你可以做的是写出长形式的^=like

out[i] = out[i] ^ in[foo(i)]
于 2020-01-15T17:00:19.360 回答
1

std::vector<bool>::operator[]返回一个代理类。您可以在cppreference上查看文档。

你可以使用static_cast<bool>所以得到一个实际的布尔值并在你的 XOR 中使用它。

out[i] = static_cast<bool>(out[i]) ^ in[foo(i)];

编辑:或者正如 Max 所指出的,简单地重写它将进行隐式转换,因此强制转换是多余的。

out[i] = out[i] ^ in[foo(i)];
于 2020-01-15T17:00:09.260 回答