这是纯粹的讨厌。首先我们来看看互换的声明:现在
template<class T>
void swap(T &left, T &right);
,operator[]()
上bitset
有两个重载:
bool operator[](size_type _Pos) const;
reference operator[](size_type _Pos);
这里reference
是bitset::reference
,在bitset
嵌套类,有效地充当代理参考其中一个基础位。它封装的是bitset
和bitset
中的一个位置。由于swap
的声明,选择了第二个过载,我们正在交换两个bitset::reference
。现在,这里变得讨厌。让我们来看看一个典型的实现互换:
template class<T> swap(T &left, T &right) {
T temp = left;
left = right;
right = temp;
}
的问题是,left
和right
是一个bitset::reference
两个引用。它们具有相同的基础数据(因为它们是代理;同样意味着两者都指向相同的bitset
!),它们只是封装了bitset
中的不同位置。因此,认为它是这样left
是位置0在一些bitset
和right
是位置1在一些bitset
和bitset
是bitset
是left
相同!让我们永远把这个bitset
称为BS
(故意选择)。
所以,
T temp = left;
说temp
是BS
位置0。
left = right;
套位置0中BS
离开位置1(同时改变temp
位置0!)
right = temp;
套位置1右位置BS
0(只设为位置1在BS
!)。所以在这个混乱的结尾有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++ 0x都没有提到与位集相关的'swap'。 – Potatoswatter 2010-01-05 05:52:49
这是否真的编译? 'test [0]'是暂时的,你不能参考... – Barry 2015-09-22 21:53:23