Как описано в документации здесь, std::bitset::operator^= возвращает *this. Исходя из этого и из «обычной» интерпретации операторов, таких как +=, |=, *=, можно было бы разумно предположить, что с учетом экземпляров std::bitset (одинакового размера) a и b выражение (a^=b).count() сохранит результат побитовой операции XOR в a, и что count() вернет количество битов в a, для которых установлено значение true. Однако, как показывает следующий минимальный пример, происходит нечто неожиданное:
#include <iostream>
#include <bitset>
int main()
{
constexpr unsigned int N=6;
std::bitset<N> a;
std::bitset<N> b;
a.flip();//111111
b[0]=1;
b[4]=1;//b is now 010001 (assuming least significan bit on the right end of the string)
std::cout<<"a= = "<<a.to_string()<<std::endl;
std::cout<<"b= = "<<b.to_string()<<std::endl;
std::cout<<"(a xor b) to string= = "<<(a^=b).to_string()<<std::endl;
//Here is the unexpected part!
std::cout<<"(a xor b) count= = "<<(a^=b).count()<<std::endl;
//Note that the following lines would produce the correct result
//a^=b;
//std::cout<<a.count()<<std::endl;
return 0;
}
На выходе
a==111111
b==010001
(a xor b) to string==101110
(a xor b) count==6 //this is wrong!!!!! It should be 4...
Быстрый взгляд на реализацию std::bitset (см. здесь), кажется, указывает на то, что возвращаемая ссылка действительно является ссылкой на объект lhs (a в моем примере). Итак ... Почему это происходит?
(a^=b) оценивается дважды.
Дело в том, что ваш комментарий неверен. Замена «разорванной» строки альтернативой дает тот же результат. Если только вы не хотели оставить в качестве альтернативы обе «ломаные» линии а также.
@RichardCritten Ааа, ладно, верно ... Спасибо ... Какая глупость с моей стороны.
в C++, как правило, если вы используете символ =, то описание того, что вы делаете, будет включать слово «равно». в случае a^=b это "a равно a ^ b", в случае a==b это "равно b" и т. д. Есть много операторов, которые имеют знак =
^ - это xor, ^= - это xorназначение. Вы не хотите модифицировать a, вам просто нужен результат a xor b.





Это не имеет ничего общего с битовым набором. Рассмотрим этот код:
int a = 2;
int b = 3;
std::cout << std::to_string(a *= b) << std::endl; // Prints 6.
std::cout << std::to_string(a *= b) << std::endl; // Prints 18.
Вы используете оператор присваивания, поэтому ваша переменная / битовый набор изменяет время каждый. В вашем случае вторая оценка дает ((a ^ b) ^ b), который, конечно же, является исходным a (у которого было установлено 6 бит).
Используйте
(a^b).count(), а не(a^=b).count(). Вы присвоениеaи переключаете состояния битов назад и вперед.