template
#include
一个bitset中保存了一些bit(字节, 只能取两个值的元素:0或1,真或假 …)
bitset模拟了一个bool类型的数组,但是优化了内存空间:总的来说,每个元素值占用一个bit(比大多数系统中最小的元素char小了8倍)
每个位置的都可以独立的访问:例如,给定一个bitset命名为foo,foo[3]访问的就是第四个元素,就像通常数组访问他的元素一样。
但是因为在C++中没有只占用一个字节的类型,bitset是通过专门的引用类型来实现每个元素单独访问的(可以查看bitset::reference)。
bitset可以通过integer值和二元内容的字符串来创建,也可以转换为interger值和字符串(查看bitset的构造函数和to_ulong、to_sting方法)。可以插入到内容为二元类型的流中,也可以从二元类型的流中提取(查看bitset适用的操作符)。
bitset的大小在编译阶段就已经确定(由模板的参数决定)。对于同样对空间进行优化并且可以动态改变大小的类,可以使用一个专门为bool类型创建的vector 类(vector)。
N:指定bitset的大小,根据所占bit的数量。可以通过bitset的成员函数bitset::size来获取。size_t是一个无符号整型。
像一个类型来引用。
这是一个嵌入式类,当在一个非const的bitset对象上使用下标操作符bitset::operator[]来访问元素的时候会返回该类型。通过一个模拟指向bool类型引用的接口来访问每个元素。
原型定义:
C++11:
class bitset::reference {
friend class bitset;
reference() noexcept; // no public constructor
public:
~reference();
operator bool() const noexcept; // convert to bool
reference& operator= (bool x) noexcept; // assign bool
reference& operator= (const reference& x) noexcept; // assign bit
reference& flip() noexcept; // flip bit value
bool operator~() const noexcept; // return inverse value
}
函数原型
构造一个bitset容器对象:
1.默认构造函数: 对象中的值都设置为0
2.由integer值初始化bitset对象: 使用val对应的bit值来初始化bitset对象,参考例子
3.使用string或着(4)中的C-string来初始化对象: 使用str中的0和(或)1的序列来初始化bitset对象的前n个值。
注意: 不管用哪个构造函数构造出来的bitset对象的大小是不可变的(大小由类模板的参数决定)。没有被构造函数赋值的位会被初始化为0。
参数
val: 将integer类型值对应的bits位的值拷贝到bitset对象的对应位置。
1.如果val的位数大于bitset的size大小,只将val的低位的size个bit赋值给bitset
2.如果val的位数小于bitset的size大小,不足的部分补零。
str: 用来初始化bitset对象的string或这C-string。构造函数最多解析字符串的n个字符(第三个构造函数是从pos的位置开始读取),然后依次将每个字符的值解析为0和1。【注意】最后读取的字符赋值给最低有效位,字符串下标0在高有效位(参考例子)。因此bitset的第一位的值是string的最右边的值,然后从右到左一次读取。如果string序列比bitset的size小,剩余的补零。
pos: 从string读取的起始位置,如果超过了str的长度会抛出out_of_range的异常。
zero,one: 来表示0和1的字符。
Example:
// constructing bitsets
#include // std::cout
#include // std::string
#include // std::bitset
int main () {
std::bitset<16> foo;
std::bitset<16> bar (0xfa2);
std::bitset<16> baz (std::string("0101111001"));
std::cout << "foo: " << foo << '\n';
std::cout << "bar: " << bar << '\n';
std::cout << "baz: " << baz << '\n';
return 0;
}
Output:
foo: 0000000000000000
bar: 0000111110100010
baz: 0000000101111001
数据竞争
构造函数3和4中会访问str中的字符。
异常和安全
1和2构造函数不会抛出异常。3和4在pos大于length的时候会抛出out_of_length的异常。
对bitset中的内容执行逐位的操作。
参数
lhs: 操作符左侧的bitset对象(操作符不会修改该值)
rhs: 操作符右边的bitset对象,操作符左侧和右侧的bitset对象的size必须相同(类模板的N相等)。
pos: 要移动的位数
is,os: 读取bitset流和bitset写入的流,流必须是0和1字符序列
返回值
1.如果是一个引用,返回左侧值(*this,is或者os)。其他情况返回操作符的执行结果(可能是一个bitset对象,或者true、false)。
Example
// bitset operators
#include // std::cout
#include // std::string
#include // std::bitset
int main ()
{
std::bitset<4> foo (std::string("1001"));
std::bitset<4> bar (std::string("0011"));
std::cout << (foo^=bar) << '\n'; // 1010 (XOR,assign)
std::cout << (foo&=bar) << '\n'; // 0010 (AND,assign)
std::cout << (foo|=bar) << '\n'; // 0011 (OR,assign)
std::cout << (foo<<=2) << '\n'; // 1100 (SHL,assign)
std::cout << (foo>>=1) << '\n'; // 0110 (SHR,assign)
std::cout << (~bar) << '\n'; // 1100 (NOT)
std::cout << (bar<<1) << '\n'; // 0110 (SHL)
std::cout << (bar>>1) << '\n'; // 0001 (SHR)
std::cout << (foo==bar) << '\n'; // false (0110==0011)
std::cout << (foo!=bar) << '\n'; // true (0110!=0011)
std::cout << (foo&bar) << '\n'; // 0010
std::cout << (foo|bar) << '\n'; // 0111
std::cout << (foo^bar) << '\n'; // 0101
return 0;
}
Output:
1010
0010
0011
1100
0110
1100
0110
0001
0
1
0010
0111
0101
数据竞争
操作中bitset的所有位都会被访问,如果涉及赋值的,值会被修改。
异常&安全
流插入和提取的时候如果出现异常保持所有对象处于有效状态(基本保证)。其他不会抛出异常
函数原型
bool operator[] (size_t pos) const;
reference operator[] (size_t pos);
功能:
返回pos位置的值(或在引用)。该操作不会检查边界。bitset::test在访问值的同时会检查边界。
参数:
pos: pos位置的bit值。如果bitset对象是const的,该函数返回一个bool值。否则的花返回一个引用,该引用模拟了一个bool的值。
Example
// bitset::operator[]
#include // std::cout
#include // std::bitset
int main ()
{
std::bitset<4> foo;
foo[1]=1; // 0010
foo[2]=foo[1]; // 0110
std::cout << "foo: " << foo << '\n';
return 0;
}
Output:
foo: 0110
数据竞争
不管bitset是不是const的,只访问都不会修改bitset。非const版本返回的引用可以用来访问和修改bitset的内容。注意,修改一个位可能会对其他的位产生影响,因此并发访问bitset的不同位不是线程安全的。
异常&安全
如果指定的pos是无效的会导致不确定的行为。如果该函数出现异常,bitset仍保持有效状态(基本保证)。
函数原型(C++11)
size_t count() const noexcept;
功能
返回bitset中设置的有效位的数量(值为1的)。获取bitset的所有成员数量(包含值为0的),使用bitset::size.
参数
无
返回值
bitset中值为1的成员数量。size_t是unsigned integer类型。
Example
// bitset::count
#include // std::cout
#include // std::string
#include // std::bitset
int main ()
{
std::bitset<8> foo (std::string("10110011"));
std::cout << foo << " has ";
std::cout << foo.count() << " ones and ";
std::cout << (foo.size()-foo.count()) << " zeros.\n";
return 0;
}
Output:
10110011 has 5 ones and 3 zeros.
数据竞争
bitset会被访问。
异常&安全
强保证:如果该函数出现异常,对bitset没有任何影响。
如果bitset的长度超出了size_t的表示范围,则抛出overflow_error的异常。
函数原型(C++11)
constexpr size_t size() noexcept;
功能
返回bitset中所有成员数量(包含值为0的),值等于创建bitset对象的时候传入的参数N。
参数
无
返回值
bitset中所有的成员数量。size_t是unsigned integer类型。
Example
// bitset::size
#include // std::cout
#include // std::bitset
int main ()
{
std::bitset<8> foo;
std::bitset<4> bar;
std::cout << "foo.size() is " << foo.size() << '\n';
std::cout << "bar.size() is " << bar.size() << '\n';
return 0;
}
Output:
foo.size() is 8
bar.size() is 4
数据竞争
无,在编译阶段确定的常量。
异常&安全
保证该函数不会抛出异常。
函数原型
bool test (size_t pos) const;
功能
返回bitset的pos下标位置是否被置位(值是不是1)。与下标操作符[]不同的是,test在访问值之前会检查pos是否有效,如果超过了bitset的size会抛出out_of_range的异常。
参数
pos: 要访问的值的下标。从最右侧的位置开始,下标从0开始。size_t是一个unsigned int类型。
返回值
如果置位了返回True,否则返回False。
Example
// bitset::test
#include // std::cout
#include // std::string
#include // std::size_t
#include // std::bitset
int main ()
{
std::bitset<5> foo (std::string("01011"));
std::cout << "foo contains:\n";
std::cout << std::boolalpha;
for (std::size_t i=0; i
Output:
foo contains:
true
true
false
true
false
数据竞争
bitset会被访问。
异常&安全
强保证:如果该函数出现异常,不会对bitset对象有任何的修改。
如果pos超出size会抛出out_of_range的异常。
函数原型
bool any() const noexcept;
功能
检测bitset中有没有被置1的位(bitset中至少有一个位被置为1)。
与函数bitset::none的功能正好相反。
参数
无
返回值
如果任意一位被置1的话返回True,否则返回False。
Example
// bitset::any
#include // std::cin, std::cout
#include // std::bitset
int main ()
{
std::bitset<16> foo;
std::cout << "Please, enter a binary number: ";
std::cin >> foo;
if (foo.any())
std::cout << foo << " has " << foo.count() << " bits set.\n";
else
std::cout << foo << " has no bits set.\n";
return 0;
}
Possible output:
Please, enter a binary number: 10110
0000000000010110 has 3 bits set.
数据竞争
bitset会被访问。
异常&安全
保证不会抛出任何异常。
函数原型(C++11)
bool none() const noexcept;
功能
检测bitset中全部为0。与函数bitset::any的功能正好相反。
参数
无
返回值
如果值全部为0返回True,否则返回False.
Example
// bitset::none
#include // std::cin, std::cout
#include // std::bitset
int main ()
{
std::bitset<16> foo;
std::cout << "Please, enter a binary number: ";
std::cin >> foo;
if (foo.none())
std::cout << foo << " has no bits set.\n";
else
std::cout << foo << " has " << foo.count() << " bits set.\n";
return 0;
}
Possible output:
Please, enter a binary number: 11010111
0000000011010111 has 6 bits set.
数据竞争
bitset会被访问。
异常&安全
保证不会抛出任何异常。
函数原型
bool all() const noexcept;
功能
检测bitset中全部为1。如果返回True,bitset中size个元素全部被置位。
参数
无
返回值
如果值全部为1返回True,否则返回False.
Example
// bitset::all
#include // std::cin, std::cout, std::boolalpha
#include // std::bitset
int main ()
{
std::bitset<8> foo;
std::cout << "Please, enter an 8-bit binary number: ";
std::cin >> foo;
std::cout << std::boolalpha;
std::cout << "all: " << foo.all() << '\n';
std::cout << "any: " << foo.any() << '\n';
std::cout << "none: " << foo.none() << '\n';
return 0;
}
Possible output:
Please, enter an 8-bit binary number: 11111111
all: true
any: true
none: false
数据竞争
bitset会被访问。
异常&安全
保证不会抛出任何异常。
函数原型(C++11)
all bits (1) bitset& set() noexcept;
single bit (2) bitset& set (size_t pos, bool val = true);
功能
设置bitset中的值:
1.将bitset中的所有值设置为1。
2.将pos位置的bit的值设置为1。
参数
pos: 指定要修改的bit的下标位置。下标从0开始,由最右边开始标记。如果pos大于等于bitset的size则会抛出out_of_range的异常。
size_t是unsigned int类型。
val: 要赋的值(或者为True、1或者为False、0)
返回值
*
this
Example
// bitset::set
#include // std::cout
#include // std::bitset
int main ()
{
std::bitset<4> foo;
std::cout << foo.set() << '\n'; // 1111
std::cout << foo.set(2,0) << '\n'; // 1011
std::cout << foo.set(2) << '\n'; // 1111
return 0;
}
Output:
1111
1011
1111
数据竞争
bitset的位会被修改
异常&安全
函数1不会抛出任何异常。如果2出现异常,基本保证bitset仍处于有效状态。
如果pos大于等于bitset的size则会抛出out_of_range的异常。
函数原型(C++11)
all bits (1) bitset& reset() noexcept;
single bit (2) bitset& reset (size_t pos);
功能
将bitset中的值为0:
1.将bitset中的所有值设置为0。
2.将pos位置的bit的值设置为0。
参数
pos: 指定要修改的bit的下标位置。下标从0开始,由最右边开始标记。如果pos大于等于bitset的size则会抛出out_of_range的异常。
size_t是unsigned int类型。
返回值
*
this
Example
// bitset::reset
#include // std::cout
#include // std::string
#include // std::bitset
int main ()
{
std::bitset<4> foo (std::string("1011"));
std::cout << foo.reset(1) << '\n'; // 1001
std::cout << foo.reset() << '\n'; // 0000
return 0;
}
Output:
1001
0000
数据竞争
bitset的位会被修改
异常&安全
函数1不会抛出任何异常。如果2出现异常,基本保证bitset仍处于有效状态。
如果pos大于等于bitset的size则会抛出out_of_range的异常。
函数原型(C++11)
all bits (1) bitset& flip() noexcept;
single bit (2) bitset& flip (size_t pos);
功能
将bitset中的值取反:
1.将bitset中的所有值取反。
2.对指定位置pos的值取反。
参数
pos: 指定要取反的bit的下标位置。下标从0开始,由最右边开始标记。如果pos大于等于bitset的size则会抛出out_of_range的异常。
size_t是unsigned int类型。
返回值
*
this
Example
// bitset::flip
#include // std::cout
#include // std::string
#include // std::bitset
int main ()
{
std::bitset<4> foo (std::string("0001"));
std::cout << foo.flip(2) << '\n'; // 0101
std::cout << foo.flip() << '\n'; // 1010
return 0;
}
Output:
0101
1010
数据竞争
bitset的位会被修改
异常&安全
函数1不会抛出任何异常。如果2出现异常,基本保证bitset仍处于有效状态。
如果pos大于等于bitset的size则会抛出out_of_range的异常。
函数原型(C++11)
template ,
class Alloc = allocator>
basic_string to_string (charT zero = charT('0'),
charT one = charT('1')) const;
功能
构造一个基础string类型对象,将bitset中的值表示为一连串的0和/或1。
该函数返回的字符串与将bitset写入到<<输出操作符得到的显示结果是相同的。
注意:该函数使用函数模板来定义返回值。默认的返回值是string。
参数
zero, one: 用来表示0和1的字符。
返回值
用来表示bitset内容的字符串。
Example
// bitset::to_string
#include // std::cout
#include // std::string
#include // std::bitset
int main ()
{
std::bitset<4> mybits; // mybits: 0000
mybits.set(); // mybits: 1111
std::string mystring =
mybits.to_string();
std::cout << "mystring: " << mystring << '\n';
return 0;
}
Output:
mystring: 1111
数据竞争
会访问bitset对象。
异常&安全
强保证:如果该函数出现异常,对bitset没有任何的影响。
函数原型
unsigned long to_ulong() const;
功能
将bitset转换为unsigned long int。返回的unsigned long int对应的二进制序列与bitset中的序列相同。
如果bitset的size太大,用unsigned long int表示不了,会抛出一个overflow_error的异常。
参数
无
返回值
二进制序列与bitset相同的unsigned long int值。
Example
// bitset::to_ulong
#include // std::cout
#include // std::bitset
int main ()
{
std::bitset<4> foo; // foo: 0000
foo.set(); // foo: 1111
std::cout << foo << " as an integer is: " << foo.to_ulong() << '\n';
return 0;
}
Output:
1111 as an integer is: 15
数据竞争
会访问bitset对象的内容。
异常&安全
强保证:如果该函数出现问题,不会对bitset对象有任何的影响
如果size太大导致超出unsigned long int的表示范围会抛出overflow_error的异常。
该函数与std::bitset::to_ulong的区别就是该函数会返回一个unsigned long long类型,其他使用方式和注意事项相同,不再重复叙述。
函数原型
template struct hash; // unspecialized
template struct hash>; // bitset specialization
bitset的hash计算。是一个一元函数的类对象,bitset定制的hash函数计算函数。
函数根据传入的bitset返回一个哈希值:哈希值的只与传入的参数有关,相同的参数返回相同的值(对于已给定的计算方式)。不同参数的返回值应该尽量不同(碰撞可能性接近1/numeric_limits
这就可以使用bitset对象作为无序容器的key(例如unordered_set 或者unordered_map)。
想了解更多可参考hash的实现
成员函数
()操作符:返回一个哈希值,类型为size_t,一个unsigned int类型的值。