這是純粹的討厭。首先我們來看看互換的聲明:現在
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