2016-09-06 35 views
7

Rozważmy ten test Jednostka:Dlaczego std :: swap nie działa z zawartością std :: bitset <n>?

std::bitset<8> temp("11010100"); 
reverseBitSet(temp); 
CPPUNIT_ASSERT(temp == std::bitset<8>("00101011")); 

Ta implementacja działa:

template<size_t _Count> static inline void reverseBitSet(std::bitset<_Count>& bitset) 
{ 
    bool val; 
    for (size_t pos = 0; pos < _Count/2; ++pos) 
    { 
     val = bitset[pos]; 
     bitset[pos] = bitset[_Count-pos-1]; 
     bitset[_Count-pos-1] = val; 
    } 
} 

Chociaż ten jeden nie:

template<size_t _Count> static inline void reverseBitSet(std::bitset<_Count>& bitset) 
{ 
    for (size_t pos = 0; pos < _Count/2; ++pos) 
    { 
     std::swap(bitset[pos], bitset[_Count-pos-1]); 
    } 
} 

Wynik jest "11011011" zamiast "00101011"

Dlaczego swap robi to źle?

+0

'operator' [zwraca 'serwer proxy] –

Odpowiedz

8

to:

std::swap(bitset[pos], bitset[_Count-pos-1]); 

powinna rzeczywista nie skompilować. operator[] dla std::bitset nie zwraca referencji, zwraca obiekt proxy. Ten obiekt proxy nie jest lwartością, więc nie może się połączyć z T& w std::swap. Zakładam, że kompilacja w ogóle oznacza, że ​​używasz MSVC, który ma rozszerzenie, które pozwala na powiązanie tymczasowych z referencjami nie-const - w którym momencie prawdopodobnie po prostu zamienisz proxy, a nie to, co są w rzeczywistości proxy odnosi się do.


Side-uwaga: nazwa _Count zarezerwowana jest w normie, podobnie jak wszelkie inne imię, które zaczyna się od _ następnie literą.

+0

' '' '' '' '' ''' '' '' '' ',' ',' ',' ',' ',' ',' ',' ',' '. – jpo38

+1

@ jpo38 Nie mówi, że zwraca referencję. Mówi, że zwraca obiekt typu ['std :: bitset :: reference'] (http://en.cppreference.com/w/cpp/utility/bitset/reference) (co jest, co prawda, mylące). – Barry

+1

@ jpo38 To _reference_ to 'std :: bitset :: reference', czyli obiekt proxy wspomniany w odpowiedzi. – skypjack