c++ 11标准模板(STL) std::vector (三)

news/2024/11/22 17:16:30/
定义于头文件 <vector>
template<

    class T,
    class Allocator = std::allocator<T>

> class vector;
(1)
namespace pmr {

    template <class T>
    using vector = std::vector<T, std::pmr::polymorphic_allocator<T>>;

}
(2)(C++17 起)

 

1) std::vector 是封装动态数组的顺序容器。

2) std::pmr::vector 是使用多态分配器的模板别名。

元素相继存储,这意味着不仅可通过迭代器,还能用指向元素的常规指针访问元素。这意味着指向 vector 元素的指针能传递给任何期待指向数组元素的指针的函数。

(C++03 起)

vector 的存储是自动管理的,按需扩张收缩。 vector 通常占用多于静态数组的空间,因为要分配更多内存以管理将来的增长。 vector 所用的方式不在每次插入元素时,而只在额外内存耗尽时重分配。分配的内存总量可用 capacity() 函数查询。额外内存可通过对 shrink_to_fit() 的调用返回给系统。 (C++11 起)

重分配通常是性能上有开销的操作。若元素数量已知,则 reserve() 函数可用于消除重分配。

vector 上的常见操作复杂度(效率)如下:

  • 随机访问——常数 O(1)
  • 在末尾插入或移除元素——均摊常数 O(1)
  • 插入或移除元素——与到 vector 结尾的距离成线性 O(n)

std::vector (对于 bool 以外的 T )满足容器 (Container) 、具分配器容器 (AllocatorAwareContainer) 、序列容器 (SequenceContainer) 、连续容器 (ContiguousContainer) (C++17 起)及可逆容器 (ReversibleContainer) 的要求。

成员函数

赋值给容器

std::vector<T,Allocator>::operator=

vector& operator=( const vector& other );

(1)

vector& operator=( vector&& other );

(2)(C++11 起)
(C++17 前)

vector& operator=( vector&& other ) noexcept(/* see below */);

(C++17 起)

vector& operator=( std::initializer_list<T> ilist );

(3)(C++11 起)

 替换容器内容。

1) 复制赋值运算符。以 other 的副本替换内容。若 std::allocator_traits<allocator_type>::propagate_on_container_copy_assignment::value 为 true ,则以源分配器的副本替换目标分配器。若源分配器与目标分配器不比较相等,则用目标( *this )分配器销毁内存,然后在复制元素前用 other 的分配器分配。 (C++11 起).、

2) 移动赋值运算符。用移动语义以 other 的内容替换内容(即从 other 移动 other 中的数据到此容器)。之后 other 在合法但未指定的状态。若 std::allocator_traits<allocator_type>::propagate_on_container_move_assignment::value 为 true ,则用源分配器的副本替换目标分配器。若它为 false 且源与目标分配器不比较相等,则目标不能取走源内存的所有权,而必须单独移动赋值逐个元素,用自己的分配器按需分配额外的内存。任何情况下,原先在 *this 中的元素要么被销毁,要么以逐元素移动赋值替换。

3) 以 initializer_list ilist 所标识者替换内容。

参数

other-用作数据源的另一容器
ilist-用作数据源的 initializer_list

返回值

*this

复杂度

1) 与 *thisother 的大小成线性。

2) 与 *this 的大小成线性,除非分配器不比较相等且不传播,该情况下与 *thisother 的大小成线性。

3) 与 *thisilist 的大小成线性。

异常

2)noexcept 规定:  

noexcept(std::allocator_traits<Allocator>::propagate_on_container_move_assignment::value
|| std::allocator_traits<Allocator>::is_always_equal::value)

(C++17 起)

注意

容器移动赋值(重载 (2) )后,除非不兼容的分配器强制逐元素赋值,否则指向 other 的引用、指针和迭代器(除了尾迭代器)都保持合法,不过指代的元素现在在 *this 中。当前标准通过 §23.2.1[container.requirements.general]/12 中的总括陈述保证这点,而 LWG 2321 下正在考虑更直接的保证。

将值赋给容器

std::vector<T,Allocator>::assign

void assign( size_type count, const T& value );

(1)

template< class InputIt >
void assign( InputIt first, InputIt last );

(2)

void assign( std::initializer_list<T> ilist );

(3)(C++11 起)

替换容器的内容。

1) 以 countvalue 的副本替换内容。

2) 以范围 [first, last) 中元素的副本替换内容。若任一参数是指向 *this 中的迭代器则行为未定义。

InputIt 为整数类型,则此重载与 (1) 拥有相同效果。

(C++11 前)

此重载仅若 InputIt 满足遗留输入迭代器 (LegacyInputIterator) 才参与重载决议。

(C++11 起)

3) 以来自 initializer_list ilist 的元素替换内容。

所有指向容器元素的迭代器、指针及引用均被非法化。尾后迭代器亦被非法化。

参数

count-容器的新大小
value-用以初始化容器元素的值
first, last-复制来源元素的范围
ilist-复制值来源的 initializer_list

复杂度

1) 与 count 成线性

2) 与 firstlast 间的距离成线性

3) 与 ilist.size() 成线性

 

返回相关的分配器

std::vector<T,Allocator>::get_allocator

allocator_type get_allocator() const;

返回与容器关联的分配器。

参数

(无)

返回值

关联的分配器。

复杂度

常数。

 

调用示例

#include <iostream>
#include <string>
#include <iterator>
#include <algorithm>
#include <functional>
#include <time.h>
#include <vector>using namespace std;struct Cell
{int x;int y;Cell() = default;Cell(int a, int b): x(a), y(b) {}Cell &operator +=(const Cell &cell){x += cell.x;y += cell.y;return *this;}Cell &operator +(const Cell &cell){x += cell.x;y += cell.y;return *this;}Cell &operator *(const Cell &cell){x *= cell.x;y *= cell.y;return *this;}Cell &operator ++(){x += 1;y += 1;return *this;}bool operator <(const Cell &cell) const{if (x == cell.x){return y < cell.y;}else{return x < cell.x;}}bool operator >(const Cell &cell) const{if (x == cell.x){return y > cell.y;}else{return x > cell.x;}}bool operator ==(const Cell &cell) const{return x == cell.x && y == cell.y;}
};std::ostream &operator<<(std::ostream &os, const Cell &cell)
{os << "{" << cell.x << "," << cell.y << "}";return os;
}int main()
{std::cout << std::boolalpha;std::mt19937 g{std::random_device{}()};srand((unsigned)time(NULL));auto generate = [](){int n = std::rand() % 10 + 110;Cell cell{n, n};return cell;};//3) 构造拥有 count 个有值 value 的元素的容器。std::vector<Cell> vector1(6, generate());std::generate(vector1.begin(), vector1.end(), generate);std::cout << "vector1:  ";std::copy(vector1.begin(), vector1.end(), std::ostream_iterator<Cell>(std::cout, " "));std::cout << std::endl;//替换容器内容。1) 复制赋值运算符。以 other 的副本替换内容。std::vector<Cell> vector2 = vector1;std::cout << "vector2:  ";std::copy(vector2.begin(), vector2.end(), std::ostream_iterator<Cell>(std::cout, " "));std::cout << std::endl;//2) 移动赋值运算符。用移动语义以 other 的内容替换内容(即从 other 移动 other 中的数据到此容器)。//之后 other 在合法但未指定的状态。std::vector<Cell> vector3 = std::move(vector1);std::cout << "vector3:  ";std::copy(vector3.begin(), vector3.end(), std::ostream_iterator<Cell>(std::cout, " "));std::cout << std::endl;std::cout << "vector1   empty: " << vector1.empty() << std::endl;//3) 以 initializer_list ilist 所标识者替换内容。std::vector<Cell> vector4 ={{101, 101}, {102, 102}, {103, 103}, {104, 104}, {105, 105}, {106, 106}};std::cout << "vector4:  ";std::copy(vector4.begin(), vector4.end(), std::ostream_iterator<Cell>(std::cout, " "));std::cout << std::endl;std::cout << std::endl;//替换容器的内容。1) 以 count 份 value 的副本替换内容。std::vector<Cell> vector5;vector5.assign(6, generate());std::cout << "vector5:  ";std::copy(vector5.begin(), vector5.end(), std::ostream_iterator<Cell>(std::cout, " "));std::cout << std::endl;//2) 以范围 [first, last) 中元素的副本替换内容。若任一参数是指向 *this 中的迭代器则行为未定义。std::vector<Cell> vector6;vector6.assign(vector5.begin(), vector5.end());std::cout << "vector6:  ";std::copy(vector6.begin(), vector6.end(), std::ostream_iterator<Cell>(std::cout, " "));std::cout << std::endl;//3) 以来自 initializer_list ilist 的元素替换内容。std::vector<Cell> vector7;vector7.assign({{101, 101}, {102, 102}, {103, 103}, {104, 104}, {105, 105}, {106, 106}});std::cout << "vector7:  ";std::copy(vector7.begin(), vector7.end(), std::ostream_iterator<Cell>(std::cout, " "));std::cout << std::endl;return 0;
}

输出

 


http://www.ppmy.cn/news/58070.html

相关文章

CSS布局基础(字体,文本,背景)

字体 常见字体设置 body {font-family: font-family: "Microsoft YaHei", Tahoma, Arial, Hiragino Sans GB,sans-serif; }浏览器从前到后匹配&#xff0c;找到可用字体结束&#xff0c;都没匹配上&#xff0c;使用浏览器默认字体 常用字号 不同浏览器默认字号可…

【6. 激光雷达接入ROS】

欢迎大家阅读2345VOR的博客【6. 激光雷达接入ROS】&#x1f973;&#x1f973;&#x1f973; 2345VOR鹏鹏主页&#xff1a; 已获得CSDN《嵌入式领域优质创作者》称号&#x1f47b;&#x1f47b;&#x1f47b;&#xff0c;座右铭&#xff1a;脚踏实地&#xff0c;仰望星空&#…

维度表设计方法

第一步&#xff1a;选择维度或新建维度。作为维度建模的核心&#xff0c;在企业级数 据仓库中必须保证维度的唯一性。以淘宝商品维度为例&#xff0c;有且只允许有 一个维度定义。 第二步&#xff1a;确定主维表。此处的主维表一般是 ODS 表&#xff0c;直接与业务 系统同步。以…

聚观早报|苹果版余额宝四天吸金69亿;​微软拟推出私有版ChatGPT

今日要闻&#xff1a;苹果版余额宝四天吸金69亿元&#xff1b;称微软拟推出私有版ChatGPT&#xff1b;特斯拉上调Model 3、Model Y售价&#xff1b;好莱坞编剧将举行15年来首次罢工&#xff1b;字节跳动要在美国卖书了 苹果版余额宝四天吸金69亿元 早些时候&#xff0c;苹果推…

【python知识】__init__.py的来龙去脉

目录 一、说明 二、包-模块-函数结构 2.1 包、模块、函数的关系 2.2 __init__.py的角色 2.3 识别包 三、__init__.py的功效 3.1 建立一个工程包 3.2 用__init__.py简化工程包 3.3 过滤 3.4 设置顶级全局变量 四、其它更多用法 4.1 高级应用 4.3 Python 3.3 及更高…

【Python】序列类型①-列表

文章目录 1. 前言2. 列表的定义3. 列表的下标访问3.1 嵌套列表的下标 4. 列表的切片操作5. 列表的遍历5.1 使用for循环进行遍历5.2 while循环进行遍历 6.添加列表元素6.1 使用append方法添加元素6.2 使用insert方法添加元素 7. 列表的拼接7.1 使用 进行拼接7.2 使用extend 进行…

语义分割学习笔记(五)U-net网络

推荐课程&#xff1a;U-Net网络结构讲解(语义分割)_哔哩哔哩_bilibili 感谢博主霹雳吧啦Wz 提供视频讲解和源码支持&#xff0c;真乃神人也&#xff01; 目录 1. U-net网络模型 2. 分割效果 3. U-Net源码解析(Pytorch版) 4. 测试结果 1. U-net网络模型 U-Net网络由两部分…

部署LVS-DR集群

引言 一、LVS-DR工作原理 LVS-DR&#xff08;Linux Virtual Server Director Server&#xff09;工作模式&#xff0c;是生产环境中最常用的一 种工作模式。 LVS-DR 模式&#xff0c;Director Server 作为群集的访问入口&#xff0c;不作为网关使用节点 Director Server 与 …