I'm using someone's class for bitmaps, which are ways of storing chess positions in 64-bit bitsets. I was wondering what the part with auto() operator
does. Is "auto" used because it returns one bit, which is why a return-type isn't specified for the function? I get that it checks that x and y are in the bounds of the chess board, and asserts an error if they aren't. I also understand that it returns a bit that corresponds to the x,y value pair for the bitset. I also don't get why the function is defined like it is, with an extra pair of parentheses. Any help is appreciated!
class BitBoard {
private:
std::bitset<64> board;
public:
auto operator()(int x, int y) {
assert(0<=x && x<=7);
assert(0<=y && y<=7);
return board[8*y+x];
}
}
};
The "extra" pair of parentheses are because you're defining operator()
, which lets instances of your class behave like functions. So if you had a:
BitBoard board;
you could get the value for x=3
, y=5
by doing:
board(3, 5)
instead of having a method you call on the board explicitly, like board.get_bit_at(3, 5)
.
The use of auto
just means it deduces the return type from std::bitset<64>
's operator[]
; since the method isn't const
qualified, this means it's just deducing the std::bitset::reference
type that std::bitset
's operator[]
uses to allow mutations via stuff like mybitset[5] = true;
, even though you can't give "true" references to single bits. If reimplemented a second time as a const
-qualified operator()
, e.g.:
auto operator()(int x, int y) const {
assert(0<=x && x<=7);
assert(0<=y && y<=7);
return board[8*y+x];
}
you could use auto
again for consistency, though it doesn't save any complexity (the return type would be bool
in that case, matching std::bitset
's const
-qualified operator[]
, no harder to type than auto
).
The choice to use operator()
is an old hack for multidimensional data structures to work around operator[]
only accepting one argument; rather than defining operator[]
to return a proxy type (which itself implements another operator[]
to enable access to the second dimension), you define operator()
to take an arbitrary number of arguments and efficiently perform the complete lookup with no proxies required.