Variable size bitset (kind of)

Правка en3, от ivan100sic, 2025-05-20 17:35:48

As we all know, the C++ standard library class std::bitset is a very powerful tool for solving all kinds of problems [1].

Due to how it is implemented and how C++ works, it is not possible to create a bitset whose size is a run-time variable. However, if the exact size is not a requirement — which is often the case, there is a way to use bitsets that are only slightly larger than required, using template metaprogramming. See the example below. To compile, C++17 or newer is required.

#include <bits/stdc++.h>
using namespace std;

struct Solver {
  int n;

  template<int N>
  void solve() {
    bitset<N> bs;
    std::cout << "Solving with bitset, N=" << N << '\n';
    // do something...
  }

  template<int N>
  void choose_size() {
    if constexpr (N >= 1'000'000) {
      solve<N>();
    } else {
      if (n <= N) {
        return solve<N>();
      }
      choose_size<2*N>();
    }
  }
};

int main() {
  int n;
  cin >> n;

  Solver s{n};
  s.choose_size<32>();
}

If the goal is to optimize further, a tighter constraint can be placed on the relative size of the bitset compared to the argument by modifying the expression in the templated function call choose_size<2*N>(). For example, we can use 5*N/4 to guarantee that the used bitset is at most 25 percent larger than required.

Keep in mind that the number of different sizes used should be a reasonable number. In any case, the compiler must generate a function for each possible template parameter N. If this rule is not respected, it is possible that the compiler will crash or outright refuse to compile the code.

Edit:

Unbeknownst to me, Golovanov399 and clyring have previously written on this exact topic in their comments [2].

Thanks to everyone for sharing additional ideas!

Теги bitset, template metaprogramming, c++

История

 
 
 
 
Правки
 
 
  Rev. Язык Кто Когда Δ Комментарий
en3 Английский ivan100sic 2025-05-20 17:35:48 19 Tiny change: ';\n }[user:Golovanov399]\n ch' -> ';\n }\n ch'
en2 Английский ivan100sic 2025-05-20 16:44:01 292
en1 Английский ivan100sic 2025-05-20 12:43:04 1728 Initial revision (published)