从整数数组构造bitset

Bar*_*rry 9 c++ bitset c++11

bitset<64>从以下构造a很容易uint64_t:

uint64_t flags = ...;
std::bitset<64> bs{flags};
Run Code Online (Sandbox Code Playgroud)

但是,有没有构建一个很好的方式bitset<64 * N>,从一个uint64_t[N],这样flags[0]会是指最低的64位?

uint64_t flags[3];
// ... some assignments
std::bitset<192> bs{flags};  // this very unhelpfully compiles
                             // yet is totally invalid
Run Code Online (Sandbox Code Playgroud)

或者我不得不set()在循环中打电话?

Win*_*ute 9

std::bitset没有范围构造函数,所以你必须循环,但是单独设置每个位std::bitset::set()是不完整的.std::bitset支持二元运算符,因此您至少可以批量设置64位:

  std::bitset<192> bs;

  for(int i = 2; i >= 0; --i) {
    bs <<= 64;
    bs |= flags[i];
  }
Run Code Online (Sandbox Code Playgroud)

更新:在评论中,@ icando提出了有效的担忧,即位移是std::bitsets的O(N)运算.对于非常大的位集,这最终会影响批量处理的性能提升.在我的基准测试中,与std::bitset<N * 64>单独设置位且不会改变输入数据的简单循环相比,a 的收支平衡点:

int pos = 0;
for(auto f : flags) {
  for(int b = 0; b < 64; ++b) {
    bs.set(pos++, f >> b & 1);
  }
}
Run Code Online (Sandbox Code Playgroud)

在某处N == 200(使用libstdc ++和x86-64上的gcc 4.9 -O2).Clang表现得更差,甚至打破了N == 160.Gcc -O3推动它N == 250.

采用较低端,这意味着如果您想使用10000位或更大的位集,这种方法可能不适合您.在32位平台(例如常见ARM)上,阈值可能会降低,因此在此类平台上使用5000位位集时请记住这一点.然而,我认为,在此之前的某个地方,你应该问自己一个bitset是否真的是容器的正确选择.