Overload the shift operators of std::bitset

2019-07-17 21:26发布

问题:

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)

回答1:

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