From a logical (non-technical) point of view, there is no advantage.
Any plain C / C++ code can be wrapped within suitable "library construct". After such wrapping, the matter of "whether this is more advantageous than that" becomes a moot question.
From a speed point-of-view, C / C++ should allow the library construct to generate code that is as efficient as the plain code that it wraps. This is however subject to:
- Function inlining
- Compile-time checking and elimination of unnecessary runtime checking
- Dead code elimination
- Many other code optimizations...
Using this kind of non-technical argument, any "missing functions" could be added by anyone, and therefore are not counted as disadvantage.
However, built-in requirements and limitations cannot be overcome with additional code. Below, I argue that the size of
std::bitset is a compile-time constant, and therefore while not counted as disadvantage, it is still something that affects user's choice.
From an aesthetic point-of-view (readability, ease of maintenance etc), there is a difference.
However, it is not apparent that the
std::bitset code immediately wins over the plain C code. One has to look at bigger pieces of code (and not some toy-sample) to say whether the use of
std::bitset has improved the human quality of the source code.
The speed of bit manipulation depends on the coding style. Coding style affects both C/C++ bit manipulation, and is equally applicable to
std::bitset as well, as explained follows.
If one writes code that uses the
operator  to read and write one bit at a time, one will have to do this multiple times if there are more than one bits to be manipulated. The same can be said of the C-style code.
bitset also has other operators, such as
operator <<=, etc., which operates on the full width of the bitset. Because the underlying machinery can often operate on 32-bit, 64-bit and sometimes 128-bit (with SIMD) at a time (in the same number of CPU cycles), code that is designed to take advantage of such multi-bit operations can be faster than "loopy" bit-manipulation code.
The general idea is called SWAR (SIMD within a register), and is a subtopic under bit manipulations.
Some C++ vendors might implement
bitset between 64-bits and 128-bits with SIMD. Some vendors might not (but might eventually do). If there is a need to know what the C++ vendor's library is doing, the only way is to look at the disassembly.
As to whether
std::bitset has limitations, I can give two examples.
- The size of
std::bitset must be known at compile time. To make an array of bits with dynamically chosen size, one will have to use
- The current C++ specification for
std::bitset does not provide a way to extract a consecutive slice of N bits from a larger
bitset of M bits.
The first one is fundamental, meaning that for people who need dynamically-sized bitsets, they must choose other options.
The second one can be overcome, because one can write some kind of adapters to perform the task, even if the standard
bitset is not extensible.
There are certain types of advanced SWAR operations that are not provided out-of-the-box from
std::bitset. One could read about these operations on this website about bit permutations. As usual, one can implement these on their own, operating on top of
Regarding the discussion on performance.
One admonition: a lot of people ask about why (something) from the standard library is much much slower than some simple C-style code. I would not repeat the prerequisite knowledge of microbenchmarking here, but I just have this advice: make sure to benchmark in "release mode" (with optimizations enabled), and make sure the code isn't being eliminated (dead code elimination) or being hoisted out of a loop (loop-invariant code motion).
Since in general we cannot tell whether someone (on the internet) were doing the microbenchmarks correctly, the only way we can get a reliable conclusion is to do our own microbenchmarks, and document the details, and submit to public review and critique. It doesn't hurt to re-do microbenchmarks that others have done before.