它没有专门化,但您仍然可以使用它。(虽然很慢)
但这是我发现的一个技巧,它使用代理类std::fill
启用。std::vector<bool>
std::_Vbase
(警告:我仅针对 MSVC2013 对其进行了测试,因此它可能不适用于其他编译器。)
int num_bits = 100000;
std::vector<bool> bit_set(num_bits , true);
int bitsize_elem = sizeof(std::_Vbase) * 8; // 1byte = 8bits
int num_elems = static_cast<int>(std::ceil(num_bits / static_cast<double>(bitsize_elem)));
在这里,因为如果你使用一个元素的任何一个位,你就需要它的整个位,所以元素的数量必须向上取整。
使用这些信息,我们将构建一个指针向量,指向位下的原始元素。
std::vector<std::_Vbase*> elem_ptrs(num_elems, nullptr);
std::vector<bool>::iterator bitset_iter = bit_set.begin();
for (int i = 0; i < num_elems; ++i)
{
std::_Vbase* elem_ptr = const_cast<std::_Vbase*>((*bitset_iter)._Myptr);
elem_ptrs[i] = elem_ptr;
std::advance(bitset_iter, bitsize_elem);
}
(*bitset_iter)._Myptr
: 通过取消引用 的迭代器std::vector<bool>
,您可以访问代理类reference
及其成员_Myptr
。
由于返回类型std::vector<bool>::iterator::operator*()
是const std::_Vbase*
, 因此将它的 constness 删除const_cast
。
现在我们得到指向这些位下面的原始元素的指针std::_Vbase* elem_ptr
。
elem_ptrs[i] = elem_ptr
: 记录这个指针,...
std::advance(bitset_iter, bitsize_elem)
: ...并继续我们的旅程,通过跳跃前一个元素持有的位来寻找下一个元素。
std::fill(elem_ptrs[0], elem_ptrs[0] + num_elems, 0); // fill every bits "false"
std::fill(elem_ptrs[0], elem_ptrs[0] + num_elems, -1); // fill every bits "true"
现在,我们可以使用std::fill
指针向量,而不是位向量。
也许有些人可能会在外部使用代理类感到不舒服,甚至删除它的常量。
但是,如果您不关心这一点并且想要快速的东西,这是最快的方法。
我在下面做了一些比较。(做了新项目,没有改变配置,发布,x64)
int it_max = 10; // do it 10 times ...
int num_bits = std::numeric_limits<int>::max(); // 2147483647
std::vector<bool> bit_set(num_bits, true);
for (int it_count = 0; it_count < it_max; ++it_count)
{
std::fill(elem_ptrs[0], elem_ptrs[0] + num_elems, 0);
} // Elapse Time : 0.397sec
for (int it_count = 0; it_count < it_max; ++it_count)
{
std::fill(bit_set.begin(), bit_set.end(), false);
} // Elapse Time : 18.734sec
for (int it_count = 0; it_count < it_max; ++it_count)
{
for (int i = 0; i < num_bits; ++i)
{
bit_set[i] = false;
}
} // Elapse Time : 21.498sec
for (int it_count = 0; it_count < it_max; ++it_count)
{
bit_set.assign(num_bits, false);
} // Elapse Time : 21.779sec
for (int it_count = 0; it_count < it_max; ++it_count)
{
bit_set.swap(std::vector<bool>(num_bits, false)); // You can not use elem_ptrs anymore
} // Elapse Time : 1.3sec
有一个警告。当您swap()
将原始向量与另一个向量结合时,指针向量就变得无用了!