从整数数组构造 bitset
Construct bitset from array of integers
从 uint64_t
构造 bitset<64>
很容易:
uint64_t flags = ...;
std::bitset<64> bs{flags};
但是有没有一种好方法可以从 uint64_t[N]
构造一个 bitset<64 * N>
,这样 flags[0]
将引用最低的 64 位?
uint64_t flags[3];
// ... some assignments
std::bitset<192> bs{flags}; // this very unhelpfully compiles
// yet is totally invalid
还是我必须循环调用 set()
?
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 是否真的是容器的正确选择。
如果从范围初始化很重要,您可以考虑使用 std::vector
它确实有一对迭代器的构造函数
从 uint64_t
构造 bitset<64>
很容易:
uint64_t flags = ...;
std::bitset<64> bs{flags};
但是有没有一种好方法可以从 uint64_t[N]
构造一个 bitset<64 * N>
,这样 flags[0]
将引用最低的 64 位?
uint64_t flags[3];
// ... some assignments
std::bitset<192> bs{flags}; // this very unhelpfully compiles
// yet is totally invalid
还是我必须循环调用 set()
?
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 是否真的是容器的正确选择。
如果从范围初始化很重要,您可以考虑使用 std::vector
它确实有一对迭代器的构造函数