一、在C++11中新加入的关键字
在C++11中加入了auto关键字。用此关键字可以指向任何类型的数据。
比如: auto p = 3 或者 string string1 = “test string”; auto& string2 = string1;
以前的空指针用NULL表示,现在针对空指针,专门有nullptr关键字用于表示空指针
在传参的时候可以用 initializer_list<int>的表示方式进行初始化。比如func(initializer_list<int> v) {}。因为用此修饰词修饰的参数是不可修改的,所以不能在函数里对v变量进行修改。不过可以对其进行遍历。传参可表示为:func({1,2,3});。当我们要用列表对类进行初始化的时候,可以用C c1{1}的方式进行初始化(因为参数加了initializer_list限制,所以可以直接用{}进行初始化)。
在C++11中加入constexpr关键字。如果在函数定义中用此关键字修饰,认为该函数为内联函数(inline)。constexpr的值只能在编译时确定,const关键字可以在运行时赋值。编译器可以对constexpr表示的变量进行优化。
在C++11中可以用nothrow表示该操作不抛出异常。比如new(nothrow) string(), delete(nothrow, s),delete[](nothrow,s)。如果这样操作,要对返回的结果进行判断。
在C++11中加入了返回值的自动匹配,比如我们对模板定义的函数进行操作如下
template<class T>
auto neg(T&& t)->decltype(-t) { return -t; } decltype表示使用t的类型作为返回类型
二、容器介绍
1. unordered_map
可以使用unordered_map<string, char> student_grade {{“Steve”, 'A'}, {"Bob", 'B'}, {"Bucky", 'D'}, {"Lucy", 'C'}}; 进行初始化,也可以直接赋值,比如student_grade["Sara"] = 'B'; 因为unordered_map是用hash表进行存储,所以可以设置hash表的bucket_count。比如用student_grade_bucket_count()显示bucket的大小,用max_load_factor()函数和reserve函数设置map的大小和使用率。比如有100元素,容器的bucket的最大平均元素值为12.5,那至少需要>100/12.5=8个桶(最少9个)才能保存所有数据
2. unordered_set
该容器不是顺序存储,可以用insert()函数进行插入,用erase()函数进行删除。如果插入值已经存在,则不做任何工作。这个容器也是用hash表进行存储,所以也可以用max_load_factor()函数和reserve函数进行大小的设置。
3. bitset
const int n = 4; bitset<n> b1; 初始化为全0,共有4bit。bitset<8> b2(7) 初始化为00000111。
bitset<4> b4("TFTF", 4, 'F', 'T') //TFTF = 1010。操作有 XOR(^),OR(|),NOT(~),AND(&),shift(>>, <<)
4. pair 在utility头文件中
pair<int, string> e { 100, "example" }; e.first可以取出100,e.second可以取出"example"
5. deque 在deque头文件中
deque<int> dq; dq.push_back(3); dq.push_front(1); dq.pop_back(); dq.pop_front(); dq[0]也可以取数据,不过不安全。
deque支持erase操作,可以用dq.erase(itr)删除数据,itr为迭代器。用dq.size()可以查看大小。dq.max_size()可以查看容器的最大容量。因为支持随机读取,所以至少在逻辑上是连续的空间。
6. multimap
该map可以有多个相同的键值。遍历可以用while(itr != mm.end() && itr->first == 2)获取所有键值为2的数据。
在使用erase(2)操作时,multimap会删除所有键值为2的数据。
7. multiset
同上,在erase操作时,删除所有该值的数据。如果查找操作,返回第一个找到的数据。
8. array array头文件中
array的长度固定,相当于数组,初始化可用array<int, 5> a = {1,2,3,4,5};
主要操作有size(), front(), back(), fill(当用此函数时,会将所有值填充为一个值,比如a.fill(2)),data()获得该array的指针。接下来可以用*(i+2)等操作像指针一样进行操作。
9. priority_queue 在头文件queue中
该容器自动对push()进来的数据进行排序,默认从大到小拍,所以用top()取出的数据为最大值。取出后,要用pop()函数删除该数。
priority_queue<int, deque<int>, greater<int>> pq表示该有限队列用deque进行存储,从小到大进行排序。
10. stringstream 头文件sstream中
操作如C中的文件操作。主要操作如下:
stringstream ss; ss << 3.1415 << ' ' << 180; ss >> rad >> deg;
ss.write("This is a test for streamstring.", 32); long p = ss.tellp();返回字符串末尾 ss.seekp(p - 4); 向前移动4字节 ss.write("cat", 3); 在此位置写入字符串 stringbuf *pbuf = ss.rdbuf(); 返回里面的字符串 pbuf->sputn("Example string\0",15); 写入15个字节 。 char buffer[80]; pbuf->sgetn(buffer, 15)从pbuf中读取15个字节到buffer中。
11. 数字修饰符
156U无符号数, 10UL无符号长整数, 1.0F制定为float,2e-5表示e的-5次方,1.2e-33L表示e的-33次方,为long double类型。
0xFDEDA表示16进制数, 0456表示8进制数,为十进制的302。cout<<hex<<h0<<dec<<h0<<oct<<h0<<endl;其中hex为16进制输出,dec为10进制输出,oct为8进制输出。
三、迭代器介绍
1. stl中的find()函数
vector<int>::iterator i = find(v.begin(), v.end(), 6)找到vector中第一个6,范围其迭代器。如果找不到,返回v.end()
2. stl中的sort函数
auto upper_bound = find(v.begin(), v.end(), 9)找到第一个vector中为9的迭代器 sort(v.begin(), upper_bound)。在sort的时候不包括upper_bound位置的值。这相当于v.end()标志。
3. stl中的insert函数
back_inserter(v) = j在容器v后面加上值为j的数。该操作支持vector,list,queue等容器。
front_inserter(v) = j在容器v前面加上值为j的数。该操作不支持vector(效率问题)
4. stl中的copy和move函数
copy(s.begin(), s.end(), back_inserter(s2));在s2后面插入s的拷贝
list<string> s(make_move_iterator(s2.begin()), make_move_iterator(s2.end()));将s2的值move到s容器中。之后s2中将没有数据。
四、枚举值类
enum class Texture { sticky, smooth, soft, rough }; 其中的枚举值类可以看成是一个为所有属性为static的类
用法为Texture t = Texture::sticky; 如果要将枚举值转换成int值,则用 int r = static_cast<int>(Texture::sticky)
可以在enum class中重载操作符。比如
Texture Texture::operator~(Texture t)
{ int value = static_cast<int>(t) ^ 0x10; return static_cast<Texture>(value); }