Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why std::swap does not work with std::bitset<n> content?

Consider this unit test:

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

This implementation works:

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;
    }
}

While this one does not:

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] );
    }
}

Result is "11011011" instead of "00101011"

Why is swap doing it wrong?

like image 651
jpo38 Avatar asked Sep 06 '16 13:09

jpo38


1 Answers

This:

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

should actual fail to compile. operator[] for a std::bitset doesn't return a reference, it returns a proxy object. That proxy object isn't an lvalue, so it cannot bind to the T& in std::swap. I'm assuming the fact that it compiles at all means that you're using MSVC which has an extension that allows binding temporaries to non-const references - at which point you're probably just swapping the proxies and not what the proxies are actually referring to.


Side-note: The name _Count is reserved by the standard, as is any other name which begins with an _ followed by a capital letter.

like image 92
Barry Avatar answered Oct 19 '22 04:10

Barry