从整数数组

时间:2015-04-27 17:21:08

标签: c++ c++11 bitset

bitset<64>

构建uint64_t很容易
uint64_t flags = ...;
std::bitset<64> bs{flags};

但是有一种很好的方法可以从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

或者我不得不在循环中呼叫set()

2 个答案:

答案 0 :(得分: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];
  }

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

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

N == 200左右(x86-64上的gcc 4.9,libstdc ++和-O2)。 Clang的表现稍差,甚至在N == 160左右。带有-O3的Gcc会将其推送到N == 250

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

答案 1 :(得分:-1)

如果从范围初始化很重要,您可以考虑使用std :: vector

它有来自迭代器对的构造函数