C++11新特性之容器相关(一)
来源:互联网 发布:org.apache.log jar包 编辑:程序博客网 时间:2024/05/22 02:19
容器的容器
在早期版本的C++标准中如果vector的元素还是vector(或者其他模板类型),定义的形式与C++11新标准略有不同。过去,必须在外层vector对象的右尖括号和其元素类型之间添加一个空格,写成vector<vector<int> >而非vector<vector<int>>。
cbegin和cend
原来的begin和end返回的iterator是否是常量取决于对应的容器类型,但是有时,即使容器不是常量类型,我们也希望获得一个const_iterator,以避免不必要的修改行为。C++11新标准中提供了cbegin和cend函数,无论容器类型,都固定返回const_iterator。
标准库的 begin和 end
C++11新标准提供了begin和end函数,可以对普通数组使用,获得头指针和尾指针,更简单更安全,定义在iterator头文件中。尾指针指向数组的尾元素的下一位置,不能进行解引用及递增操作。
新的赋值方式
C++11允许使用一个{}包围的初始值列表来进行赋值。如果等号左侧是个容器,那么怎么赋值由容器决定。
vector<int> c3; c3 = {0, 1, 2,3, 4}; // 不能是圆括号
initializer_list
C++11新标准中新增了initializer_list类型,使用vector v= {0, 1, 2, 3, 4}这种初始化形式时,就隐式的使用了initializer_list:每当在程序中出现一段以{}包围的字面量时,就会自动构造一个initializer_list对象。
另外,initializer_list的另一个作用就在于作为函数的形参(参数类型相同),这样的函数可以方便的传入以{}包围的不定长列表:
void print_list(initializer_list<int>il){ for(autoit = il.begin(); it != il.end(); it++) { cout<<*it<<'\t'; //*it= 100; // wrong. initializer_list element is read-only. } cout<<endl;}print_list({0, 1, 2, 3, 4});print_list({0, 1, 2, 3, 4, 5});但是,需要注意的是,initializer_list中的元素是只读的。
array
C++11标准中提供了定长数组容器array,相比于普通数组更安全、更易使用。array是定长数组,所以不支持诸如插入、删除等改变容器大小的操作,但是可以对元素进行赋值改变其值。
array<int, 5> c4 = {0, 1, 2, 3, 4};c4[3] = 100; for(auto it = c4.begin(); it != c4.end();it++){ cout<<*it<<'\t';}cout<<endl;
forward_list
C++11标准中增加了新的容器forward_list,提供了一个快速的、安全的单向链表实现。因为是单向链表,所以也就没有rbegin、rend一类的函数支持了。同样是因为单向链表的缘故,无法访问到给定元素的前驱,所以没有提供insert函数,而对应提供了一个insert_after函数,用于在给定元素之后插入节点。erase_after、emplace_after同理。
forward_list<int> c5 = {3, 4};c5.push_front(2);c5.push_front(1);auto it = c5.before_begin();c5.insert_after(it, 0);
shrink_to_fit
一般可变长容器会预先多分配一部分内存出来,以备在后续增加元素时,不用每次都申请内存。所以有size和capacity之分。size是当前容器中存有元素的个数,而capacity则是在不重新申请内存的情况下,当前可存放元素的最大数目。而shrink_to_fit就表示将capacity中的多余部分退回,使其回到size大小。但是,这个函数的具体效果要依赖于编译器的实现……
vector<int> c11;for(int i = 0; i < 24; i++) c11.push_back(i);cout<<c11.size()<<'\t'<<c11.capacity()<<endl;c11.shrink_to_fit();cout<<c11.size()<<'\t'<<c11.capacity()<<endl;
无序关联容器
C++11新标准中引入了对map、set等关联容器的无序版本,叫做unorderer_map、unordered_set。无序关联容器不使用键值的比较操作来组织元素顺序,而是使用哈希。这样在某些元素顺序不重要的情况下,效率更高。
emplace
emplace操作将使用接受的参数构造一个对应容器中的元素,并插入容器中。这一点,使用普通的insert、push操作是做不到的。
class TestData{public: TestData(stringname, int age, double salary): name(name), age(age), salary(salary) {}private: stringname; intage; doublesalary;};vector<TestData> c10;c10.emplace_back("yubo", 26,100000000000.0);//c10.push_back("laowang", 56,10.5); // wrong. no 3 params push_backc10.push_back(TestData("laowang",56, 10.5));cout<<c10.size()<<endl;
新标准引入了三个新成员emplace_front、emplace和emplace_back,这些操作构造而不是拷贝元素。这些操作分别对应push_front、insert和push_back。
当调用push或insert成员函数时,我们将元素类型的对象传递给它们,这些对象被拷贝到容器中。而当我们调用一个emplace成员函数时,则是将参数传递给元素类型的构造函数。emplace成员使用这些参数在容器管理的内存空间中直接构造元素。
emplace函数的参数根据元素类型而变化,参数必须与元素类型的构造函数相匹配。
- C++11新特性之容器相关(一)
- C++ 11 新特性之容器相关特性
- C++11新特性——容器相关(二)swap
- Oracle 12c 新特性之 Multitenant Architecture (一)
- C+11 新特性
- C++11新特性——容器相关(三)tuple
- C++11 中容器相关特性
- C++11中容器相关特性
- C#: VS2008的新特性(一)
- C++11 新特性<一>
- 【C++】C++11新特性 之 lambda表达式的使用
- [C++]C++11新特性
- 【C++】 C++11新特性
- JDK7新特性之概述(一)
- java8新特性之lambda表达式(一)
- C++11新特性--线程库相关
- C++11之新特性
- C# 3.0新特性之扩展函数(相关文章)
- Learning Task Grouping and Overlap in Multi-Task Learning
- Retrofit的使用
- 12312313
- win10 vs2015 libxml2编译 各种版本
- 软件测试学习笔记(三)——软件测试过程
- C++11新特性之容器相关(一)
- ActiveMQ-JMS(三):接收消息
- java多线程和并发基础面试题
- ubuntu1404下安装anaconda
- ListView的Item嵌套ListView的显示和滑动的问题解决
- 写在伊始
- 通用页面框架CmPage(二):业务模块的基本思路
- XML实用属性
- OpenGL 透视投影 齐次裁剪空间 深度缓存