vector为何在STL中独树一帜,其特殊性体现在哪些方面?

2026-04-29 14:576阅读0评论SEO资源
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计887个文字,预计阅读时间需要4分钟。

vector为何在STL中独树一帜,其特殊性体现在哪些方面?

前言:起因是这样的,前天在查C++11的range base for loop相关的内容时,看到说vector是一个proxy iterator,非常特殊,于是好奇地研究了一下。

首先,vector并不是一个通常意义上的vector。它是一个特殊的容器,用于存储布尔值。其特殊性在于,它内部实现为一个位域(bit field),这意味着每个布尔值只占用一个比特位,从而大大节省了空间。

由于vector的特殊性,它的迭代器(iterator)也不同于一般的迭代器。它是一个proxy iterator,即代理迭代器。这意味着vector的迭代器并不是直接指向存储数据的内存地址,而是指向一个内部的proxy对象。这个proxy对象负责将迭代器的操作转换为对位域的操作。

这种设计虽然节省了空间,但也带来了一些不便。例如,你不能使用普通的迭代器操作,如++、*等,来直接访问vector中的元素。你需要使用特殊的操作符来访问每个布尔值。

总的来说,vector是一个非常有意思的研究对象,它展示了C++语言在容器设计上的巧妙之处。

vector为何在STL中独树一帜,其特殊性体现在哪些方面?

前言

起因是这样的,昨天在查C++11的range base for loop相关的东西的时候,看到说vector< bool >是一个proxy iterator,非常的特殊,于是就好奇的研究了一下。

首先vector< bool> 并不是一个通常意义上的vector容器,这个源自于历史遗留问题。

早在C++98的时候,就有vector< bool>这个类型了,但是因为当时为了考虑到节省空间的想法,所以vector< bool>里面不是一个Byte一个Byte储存的,它是一个bit一个bit储存的!

因为没有直接去给一个bit来操作,所以用operator[]的时候,正常容器返回的应该是一个对应元素的引用,但是对于vector< bool>实际上访问的是一个”proxy reference”而不是一个”true reference”,返回的是”std::vector< bool>:reference”类型的对象。

而一般情况情况下

vector<bool> c{ false, true, false, true, false }; bool b = c[0]; auto d = c[0];

对于b的初始化它其实暗含了一个隐式的类型转换。而对于d,它的类型并不是bool,而是一个vector< bool>中的一个内部类。

而此时如果修改d的值,c中的值也会跟着修改

d = true; for(auto i:c) cout<<i<<" "; cout<<endl; //上式会输出1 1 0 1 0

而如果c被销毁,d就会变成一个悬垂指针,再对d操作就属于未定义行为。

所以对于容器一些基本的操作它并不能满足,诸如取地址给指针初始化操作

vector<bool> c{ false, true, false, true, false }; bool &tmp = c[0]; //错误,不能编译,对于引用来说,因为c[0]不是一个左值 bool *p = &c[0]; //错误,不能编译,因为无法将一个临时量地址给绑定到指针

所以为什么说vector< bool>不是一个标准容器,就是因为它不能支持一些容器该有的基本操作。

What is the correct way of using C++11's range-based for?

条款6:当auto推导出意外的类型时,使用显式的类型初始化语义

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对自由互联的支持。

本文共计887个文字,预计阅读时间需要4分钟。

vector为何在STL中独树一帜,其特殊性体现在哪些方面?

前言:起因是这样的,前天在查C++11的range base for loop相关的内容时,看到说vector是一个proxy iterator,非常特殊,于是好奇地研究了一下。

首先,vector并不是一个通常意义上的vector。它是一个特殊的容器,用于存储布尔值。其特殊性在于,它内部实现为一个位域(bit field),这意味着每个布尔值只占用一个比特位,从而大大节省了空间。

由于vector的特殊性,它的迭代器(iterator)也不同于一般的迭代器。它是一个proxy iterator,即代理迭代器。这意味着vector的迭代器并不是直接指向存储数据的内存地址,而是指向一个内部的proxy对象。这个proxy对象负责将迭代器的操作转换为对位域的操作。

这种设计虽然节省了空间,但也带来了一些不便。例如,你不能使用普通的迭代器操作,如++、*等,来直接访问vector中的元素。你需要使用特殊的操作符来访问每个布尔值。

总的来说,vector是一个非常有意思的研究对象,它展示了C++语言在容器设计上的巧妙之处。

vector为何在STL中独树一帜,其特殊性体现在哪些方面?

前言

起因是这样的,昨天在查C++11的range base for loop相关的东西的时候,看到说vector< bool >是一个proxy iterator,非常的特殊,于是就好奇的研究了一下。

首先vector< bool> 并不是一个通常意义上的vector容器,这个源自于历史遗留问题。

早在C++98的时候,就有vector< bool>这个类型了,但是因为当时为了考虑到节省空间的想法,所以vector< bool>里面不是一个Byte一个Byte储存的,它是一个bit一个bit储存的!

因为没有直接去给一个bit来操作,所以用operator[]的时候,正常容器返回的应该是一个对应元素的引用,但是对于vector< bool>实际上访问的是一个”proxy reference”而不是一个”true reference”,返回的是”std::vector< bool>:reference”类型的对象。

而一般情况情况下

vector<bool> c{ false, true, false, true, false }; bool b = c[0]; auto d = c[0];

对于b的初始化它其实暗含了一个隐式的类型转换。而对于d,它的类型并不是bool,而是一个vector< bool>中的一个内部类。

而此时如果修改d的值,c中的值也会跟着修改

d = true; for(auto i:c) cout<<i<<" "; cout<<endl; //上式会输出1 1 0 1 0

而如果c被销毁,d就会变成一个悬垂指针,再对d操作就属于未定义行为。

所以对于容器一些基本的操作它并不能满足,诸如取地址给指针初始化操作

vector<bool> c{ false, true, false, true, false }; bool &tmp = c[0]; //错误,不能编译,对于引用来说,因为c[0]不是一个左值 bool *p = &c[0]; //错误,不能编译,因为无法将一个临时量地址给绑定到指针

所以为什么说vector< bool>不是一个标准容器,就是因为它不能支持一些容器该有的基本操作。

What is the correct way of using C++11's range-based for?

条款6:当auto推导出意外的类型时,使用显式的类型初始化语义

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对自由互联的支持。