Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write a std::bitset template that works on 32 and 64-bit

Consider the following code

template<unsigned int N> void foo(std::bitset<N> bs)
{ /* whatever */ }

int main()
{
    bitset<8> bar;
    foo(bar);
    return 0;
}

g++ complains about this on 64 bit because the <8> gets interpreted as an unsigned long int, which doesn't exactly match the template. If I change the template to say unsigned long int, then 32-bit compiles complain.

Obviously one way to fix this is to change bitset<8> to bitset<8ul>, but is there any way to re-write the template part so that it will work with whatever the default interpretation of a numeric literal is?

like image 547
Tyler McHenry Avatar asked Mar 14 '09 01:03

Tyler McHenry


People also ask

What is the max size of BitSet?

The maximum element in the set is the size - 1st element. The default size of the bit set is 64-bit space. If the bit is set at index larger than the current BitSet size, it increases its bit space in the multiplication of 64*n, where n starts from 1, 2, 3, so on.

How do I convert BitSet to all bits to 1?

bitset::set() is a built-in STL in C++ which sets the bit to a given value at a particular index. If no parameter is passed, it sets all bits to 1. If only a single parameter is passed, it sets the bit at that particular index to 1.

How is BitSet implemented in C++?

Let's implement bitset in C++, such that following operations can be performed in stated time complexities : init(int size): initializes a bitset of size number of 0 bits. void fix(int pos): Change the bit at position pos to 1.

Is BitSet faster than vector bool?

As bitset stores the same information in compressed manner the operation on bitset are faster than that of array and vector.


2 Answers

The problem isn't whether or not you write 8u or 8. The problem has to do with the type of the template parameter of your function template. Its type has to match the one used in the declaration of std::bitset. That's size_t according to the Standard (section 23.3.5)

namespace std {
    template<size_t N> class bitset {
    public:
    // bit reference:
        ...

The exception are array dimensions, for which you can use any integer type (even bool - then the only size that can be accepted is 1 of course):

// better size_t (non-negative), but other types work too
template<int N> void f(char(&)[N]);

But in other occasions, types have to match. Note that this is only true for autodeduced template arguments, but not for explicitly given ones. The reason is that for deduced ones, the compiler tries to figure out the best match between actual template arguments and what it deduced from the call to it. Many otherwise implicit conversions are disallowed then. You have the full range of conversions available if you put the argument explicit (ignoring the solution of using size_t now to make my point)

template<int N> void foo(std::bitset<N> bs)
{ /* whatever */ }

int main() {
    bitset<8> bar;
    foo<8>(bar); // no deduction, but full range of conversions
}
like image 135
Johannes Schaub - litb Avatar answered Nov 17 '22 01:11

Johannes Schaub - litb


Use size_t. So sayeth the MSDN at least.

like image 4
MSN Avatar answered Nov 17 '22 02:11

MSN