Побитовые операции над ОДНОЙ БИТОМ std :: vector <bool>. Почему ошибка? - PullRequest
1 голос
/ 15 января 2020

Я придумал набор правил для преобразования одного набора бит в другой.

Для того, чтобы они работали, мне в основном нужно xor определенного количества битов в исходном наборе битов (скажем, result[i]=source[foo(i)]^source[bar(i)], где foo и bar проверяются на наличие границ). Так как я хочу иметь возможность изменять размер набора, я решил go с 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)]
   }
}

Однако, это дает мне ошибку:

Нет жизнеспособного перегруженного ^ =

Что я могу сделать, чтобы иметь возможность делать это?

Ответы [ 3 ]

4 голосов
/ 15 января 2020

std::vector<bool> грязно в лучшем случае и мерзость в худшем. Его operator[] не возвращает bool&, а скорее прокси-объект ( см. Здесь ). Этот прокси не имеет перегрузок для всех возможных побитовых операций, поэтому вы должны использовать ifs, его operator=(bool) или его flip().

РЕДАКТИРОВАТЬ: я просто прочитал ваш код, а не ваше описание, что вы хотите делать. Установка xor для двух битов вообще не проблема:

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, если ни один из них не прошел его.

2 голосов
/ 15 января 2020

std::vector<bool> - это специальный контейнер. Это похоже на std::vector<int>, но стандарт позволяет std::vector<bool> упаковывать свои элементы в отдельные биты, что означает, что он возвращает прокси-объект при использовании operator[]. Этот объект не перегружен на operator ^=, поэтому вы не можете его использовать. Что вы можете сделать, это написать длинную форму ^= как

out[i] = out[i] ^ in[foo(i)]
1 голос
/ 15 января 2020

std::vector<bool>::operator[] возвращает прокси-класс. Вы можете просмотреть документацию по cppreference .

. Вы можете использовать static_cast<bool>, чтобы получить фактическое значение bool и использовать его в своем XOR.

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

Редактировать: Или, как указал Макс, простое переписывание приведет к неявному преобразованию, поэтому приведение будет избыточным.

out[i] = out[i] ^ in[foo(i)];
...