Search code examples
c++operator-overloadingstd-bitset

Overload the shift operators of std::bitset


I'd like to use the shift operators as doing a bit rotation instead of their actual bit shift. This is my expected behavior:

std::bitset<8> b8("1010"); // b8 = 00001010 
b8 <<= 5;                  // b8 = 01000001

So I try and overloaded the <<= operator, referencing the bitset definition, as followed:

#include <iostream>
#include <bitset>

using namespace std;

template <size_t size>
bitset<size>& bitset<size>::operator<< (size_t pos) noexcept { // an error at here

}

I've got an error at keyword operator:

Out-of-line definition of 'operator<<' does not match any declaration in 'bitset<_Size>'

How can I fix it? My env. is:

  • Xcode : Version 9.1 (9B55)
  • LLVM(llvm-g++ -v) : Apple LLVM version 9.0.0 (clang-900.0.38)

Solution

  • std::bitset::operator<<= is a member function of the template class std::bitset. You cannot redefine this operator. And you cannot even hide it with another:

    template <std::size_t size>
    std::bitset<size>& operator<<=(std::bitset<size>& bitset, std::size_t count) noexcept {
        // ...
        return bitset;
    }
    

    This compiles but achieves nothing since when you write b8 <<= 5, unqualified-id lookup finds std::bitset::operator<<= before considering your free function.

    You should use another operator, define a rotate function, or define a wrapper rotate class:

    struct rotate
    {
        rotate(std::size_t n) : value(n) {}
        std::size_t value;
    };
    
    
    template <std::size_t size>
    std::bitset<size>& operator<<=(std::bitset<size>& bitset, rotate r) noexcept {
        bitset = bitset << r.value | bitset >> (size-r.value);
        return bitset;
    }
    

    usage:

    std::bitset<8> b8("1010"); // b8 = 00001010 
    b8 <<= rotate(5);          // b8 = 01000001
    

    demo on coliru