Побитовые операции над ОДИНОЧНЫМ БИТОМ std :: vector <bool>.

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

Для того, чтобы они работали, мне в основном нужно xor определенное количество битов в исходном наборе битов (скажем, 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)]
   }
}

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

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

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

Всего 3 ответа


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 если никто из них не пройдет.


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

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

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)];

Есть идеи?

10000