gpt4 book ai didi

c++ - 为什么 std::bitset 实例中的 std::swap of Bits 不起作用?

转载 作者:可可西里 更新时间:2023-11-01 15:46:04 25 4
gpt4 key购买 nike

在下面的示例中,我希望交换位。相反,第二位被覆盖,但为什么以及如何实现预期的行为?

#include <iostream>
#include <string>
#include <algorithm>

using namespace std;

int main()
{
bitset<2> test(string("10"));
cout << test; // Prints "10"
swap(test[0], test[1]);
cout << test; // Prints "11", why not "01"?
}

最佳答案

这纯粹是令人讨厌的。首先我们要看swap的声明:

template<class T>
void swap(T &left, T &right);

现在,bitset 上的 operator[]() 有两个重载:

bool operator[](size_type _Pos) const;
reference operator[](size_type _Pos);

这里的 referencebitset::referencebitset 中的一个嵌套类,它有效地充当了底层对象之一的代理引用位。它封装的是bitsetbitset中的一个位置。由于 swap 的声明,选择了第二个重载,我们正在交换两个 bitset::reference。现在这里是它变得讨厌的地方。让我们看一下交换的典型实现:

template class<T> swap(T &left, T &right) {
T temp = left;
left = right;
right = temp;
}

问题是 leftright 都是对 bitset::reference 的引用。它们具有相同的底层数据(因为它们是代理;相同意味着两者都指向相同的 bitset!)它们只是封装了该 bitset 中的不同位置。因此,可以这样想 left 是某些 bitset 中的位置 0,right 是某些 bitset 中的位置 1并且 bitsetleft 相同 bitset!让我们永远将此 bitset 称为 BS(有意选择)。

所以,

T temp = left;

表示 tempBS 中的位置 0。

left = right;

将左边的位置 0 设置为 BS 中的位置 1(同时更改 temp 中的位置 0!)

right = temp;

将右侧的位置 1 设置为 BS 中的位置 0(刚刚设置为 BS 中的位置 1!)。所以在这个困惑的结尾,位置 0 就是位置 1 的位置,而位置 1 没有改变!现在,因为位置 0 是 LSB,位置 1 是 MSB,所以“10”变成了“11”。丑。

您可以使用 template specialization 来解决这个问题:

namespace std {
template<>
void swap<bitset<2>::reference>(
bitset<2>::reference &left,
bitset<2>::reference &right
) {
bool temp = (bool)left;
left = (bool)right;
right = (bool)temp;
}
}

然后:

int main() {
bitset<2> test(string("10"));
cout << test; // Prints "10"
swap(test[0], test[1]);
cout << test; // Prints "01", hallelujah!
}

关于c++ - 为什么 std::bitset 实例中的 std::swap of Bits 不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2003255/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com