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

news2024/9/23 3:34:08
定义于头文件 <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) 的要求。

 

成员函数

构造 vector

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

vector();

(1)(C++17 前)

vector() noexcept(noexcept(Allocator()));

(C++17 起)

explicit vector( const Allocator& alloc );

(2)(C++17 前)

explicit vector( const Allocator& alloc ) noexcept;

(C++17 起)
explicit vector( size_type count,

                 const T& value = T(),

                 const Allocator& alloc = Allocator());
(3)(C++11 前)
         vector( size_type count,

                 const T& value,

                 const Allocator& alloc = Allocator());
(C++11 起)

explicit vector( size_type count );

(4)(C++11 起)
(C++14 前)

explicit vector( size_type count, const Allocator& alloc = Allocator() );

(C++14 起)
template< class InputIt >

vector( InputIt first, InputIt last,

        const Allocator& alloc = Allocator() );
(5)

vector( const vector& other );

(6)

vector( const vector& other, const Allocator& alloc );

(6)(C++11 起)

vector( vector&& other );

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

vector( vector&& other ) noexcept;

(C++17 起)

vector( vector&& other, const Allocator& alloc );

(8)(C++11 起)

vector( std::initializer_list<T> init,
        const Allocator& alloc = Allocator() );

(9)(C++11 起)

从各种数据源构造新容器,可选地使用用户提供的分配器 alloc

1) 默认构造函数。构造拥有默认构造的分配器的空容器。

2) 构造拥有给定分配器 alloc 的空容器。

3) 构造拥有 count 个有值 value 的元素的容器。

4) 构造拥有个 count 默认插入的 T 实例的容器。不进行复制。

5) 构造拥有范围 [first, last) 内容的容器。

InputIt 是整数类型,则此构造函数拥有的效果同 vector(static_cast<size_type>(first), static_cast<value_type>(last), a) 。

(C++11 前)

此重载仅若InputIt 满足遗留输入迭代器 (LegacyInputIterator) 才参与重载决议,以避免和重载 (2) 的歧义。

(C++11 起)

6) 复制构造函数。构造拥有 other 内容的容器。若不提供 alloc ,则如同通过调用 std::allocator_traits<allocator_type>::select_on_container_copy_construction(other.get_allocator()) 获得分配器。

7) 移动构造函数。用移动语义构造拥有 other 内容的容器。分配器通过属于 other 的分配器移动构造获得。移动后,保证 other 为 empty() 。

8) 有分配器扩展的移动构造函数。以 alloc 为新容器的分配器,从 other 移动内容;若 alloc != other.get_allocator() ,则它导致逐元素移动。(该情况下,移动后不保证 other 为空)

9) 构造拥有 initializer_list init 内容的容器。

参数

alloc-用于此容器所有内存分配的分配器
count-容器的大小
value-以之初始化容器元素的值
first, last-复制元素的来源范围
other-用作初始化容器元素来源的另一容器
init-用作初始化元素来源的 initializer_list

复杂度

1-2) 常数

3-4) 与 count 成线性

5) 与 firstlast 的距离成线性

6) 与 other 的大小成线性

7) 常数。

8) 若 alloc != other.get_allocator() 则为线性,否则为常数。

9) 与 init 的大小成线性。

异常

Allocator::allocate 的调用可能抛出。

注意

在容器移动构造(重载 (7) )后,指向 other 的引用及迭代器(除了尾迭代器)保持合法,但指代现于 *this 中的元素。当前标准由 [container.requirements.general]/12 中的总括陈述作出此保证,而 LWG 2321 正在考虑更严格的保证。
重载 (4) 对如 int 的非类类型元素清零,这与 new[] 将元素保持未初始化的行为不同。为匹配 new[] 的行为,可提供保留元素未初始化的自定义 Allocator::construct 。

 

析构 vector

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

~vector();

销毁容器。调用元素的析构函数,然后解分配所用的存储。注意,若元素是指针,则不销毁所指向的对象。

复杂度

与容器大小成线性。

 

调用示例

#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;
    };

    //从各种数据源构造新容器,可选地使用用户提供的分配器 alloc 。
    //1) 默认构造函数。构造拥有默认构造的分配器的空容器。
    //2) 构造拥有给定分配器 alloc 的空容器。
    std::vector<Cell> vector1;
    std::cout << "vector1   empty: " << vector1.empty() << std::endl;

    //3) 构造拥有 count 个有值 value 的元素的容器。
    std::vector<Cell> vector2(6, generate());
    std::cout << "vector2:  ";
    std::copy(vector2.begin(), vector2.end(), std::ostream_iterator<Cell>(std::cout, " "));
    std::cout << std::endl;

    //4) 构造拥有个 count 默认插入的 T 实例的容器。不进行复制。
    std::vector<Cell> vector3(6);
    std::cout << "vector3:  ";
    std::copy(vector3.begin(), vector3.end(), std::ostream_iterator<Cell>(std::cout, " "));
    std::cout << std::endl;

    //5) 构造拥有范围 [first, last) 内容的容器。
    //6) 复制构造函数。构造拥有 other 内容的容器。若不提供 alloc ,则如同通过调用获得分配器
    std::vector<Cell> vector4(vector2.begin(), vector2.end());
    std::cout << "vector4:  ";
    std::copy(vector4.begin(), vector4.end(), std::ostream_iterator<Cell>(std::cout, " "));
    std::cout << std::endl;

    //7) 移动构造函数。用移动语义构造拥有 other 内容的容器。
    //分配器通过属于 other 的分配器移动构造获得。移动后,保证 other 为 empty() 。
    //8) 有分配器扩展的移动构造函数。以 alloc 为新容器的分配器,
    //从 other 移动内容;若 alloc != other.get_allocator() ,则它导致逐元素移动。
    std::vector<Cell> vector5(std::move(vector2));
    std::cout << "vector5:  ";
    std::copy(vector5.begin(), vector5.end(), std::ostream_iterator<Cell>(std::cout, " "));
    std::cout << std::endl;
    std::cout << "vector2   empty: " << vector2.empty() << std::endl;

    //9) 构造拥有 initializer_list init 内容的容器。
    std::vector<Cell> vector6({{101, 101}, {102, 102}, {103, 103},
        {104, 104}, {105, 105}, {106, 106}});
    std::cout << "vector6:  ";
    std::copy(vector6.begin(), vector6.end(), std::ostream_iterator<Cell>(std::cout, " "));
    std::cout << std::endl;

    return 0;
}

输出

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/480003.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

马上五一了,带大家玩一下五子棋——C语言

五一祝福 因为这篇博文实在五一这天完成的&#xff0c;所以呢&#xff0c;在介绍五子棋之前&#xff0c;先祝各位支持小白的大佬都五一快乐&#xff01; 花了点时间下了个“五一快乐”的五子棋&#xff0c;哈哈哈哈哈哈&#xff0c;还不太熟练&#xff0c;所以写的有点丑&…

常用 Composition API【VUE3】

二、常用 Composition API 7. 计算属性与监视 7.1 computed函数 与Vue2.x中computed配置功能一致写法 <template><h1>一个人的信息</h1>姓&#xff1a;<input type"text" v-model"person.firstName"><br><br>名&a…

【ROS 开发神器 Visual Studio Code 的安装和设置】

【ROS 开发神器 Visual Studio Code 的安装和设置】 1. Visual Studio Code的安装1.1 点击deb文件下载1.2 安装VScode1.3 启动软件1.4 添加收藏夹 2. 导入工作空间2.1 熟悉Vscode基本界面2.2 添加工作空间 3. 安装简体中文语言4. 安装ROS插件5. 安装CMake插件6. 安装括号颜色插…

SpringBoot 中的加密模块

Spring Boot 是一款流行的 Java 开发框架&#xff0c;它提供了多种加密模块&#xff0c;用于保护数据的安全性。本文将介绍 Spring Boot 中的加密模块&#xff0c;包括对称加密、非对称加密和哈希加密等&#xff0c;同时还会提供相应的代码示例。 一、对称加密 对称加密是一种…

改进YOLOv8 | 即插即用篇 | 全维动态卷积 |《 OMNI-DIMENSIONAL DYNAMIC CONVOLUTION》

单个静态卷积核是现代卷积神经网络(CNNs)的常见训练范式。然而,最近的动态卷积研究表明,学习加权为其输入依赖注意力的n个卷积核的线性组合可以显著提高轻量级CNNs的准确性,同时保持高效的推理。然而,我们观察到现有的作品通过卷积核空间的一个维度(关于卷积核数量)赋予…

关于密码学的进一步答疑:SSL和TLS的区别、CA和CT的关系

《密码学&#xff1a;一文读懂常用加密技术原理及其逻辑与应用方法》一文一经发布后&#xff0c;后台收到了许多私信&#xff0c;承蒙喜爱&#xff0c;这篇文章将主要对后台收到的高频问题予以统一回应。 问题一: 在讨论加密解密的过程中&#xff0c;常常在同一语境下同时出现S…

设计模式之原型模式(深拷贝浅拷贝)

目录 1、什么是原型模式 2、前置知识&#xff08;深拷贝&浅拷贝&#xff09; 2.1 浅拷贝 2.2 深拷贝 3、代码实现 3.1 通过Object中的clone方法实现浅拷贝 3.2 通过对象流来实现深拷贝 4、原型模式总结 4.1 优缺点 4.2 使用场景 4.3 对比直接new对象有何不同 1、…

如何使用递归函数实现Excel列号转换列标

在Excel中&#xff0c;列标与列号转换是VBA开发过程中经常用到的功能&#xff0c;下面这篇博客为大家解释了多种方法。 【Excel列标与列号转换】 那么这篇博文的核心是“递归过程”&#xff0c;实现这个功能并不是必须使用递归过程&#xff0c;但是这也不失为一种实现方法&am…

【Android入门到项目实战-- 8.2】—— 使用HTTP协议访问网络

目录 一、使用HttpURLConnection 1、使用Android的HttpURLConnection步骤 1&#xff09;获取HttpURLConnection实例 2)设置HTTP请求使用的方法 3)定制HTTP请求&#xff0c;如连接超时、读取超时的毫秒数 4)调用getInputStream()方法获取返回的输入流 5)关闭HTTP连接 2、…

NXP - LPC1769与LPC1768的区别

文章目录 NXP - LPC1769与LPC1768的区别概述笔记General description验证结论END NXP - LPC1769与LPC1768的区别 概述 openpnp设备用到了冰沙主板. 冰沙主板的主控MCU用到了LPC1769, 想着研究一下. 订了OM13085UL, 遥遥无期… 买了LPC MCU的书, 里面提到了书的作者的网店, 居…

python+vue精品课程建设制作django服务网站系统

功能介绍通篇文章的撰写基础是实际的应用需要&#xff0c;然后在架构系统之前全面复习大学所修习的相关知识以及网络提供的技术应用教程&#xff0c;以视频建设制作服务的实际应用需要出发&#xff0c;架构系统来改善现视频建设制作服务工作流程繁琐等问题。不仅如此以操作者的…

kotlin在鸿蒙开发中的实践

先说一说kotlin 我们知道&#xff1a; kotlin目前是安卓首选的编程语言。 安卓逐渐抛弃java&#xff0c;拥抱kotlin这是大的趋势。 kotlin的最大优点就是与java的互操作性。 kotlin编译的产物和java一样是bytecode(不抬杠&#xff0c;本文只说面向jvm的kotlin)。 kotlin是一…

Cadence基础操作:Schematic编辑

本文转载自B站up主:_WithB&#xff0c;原文链接如下&#xff1a;https://www.bilibili.com/read/cv20414466 鼠标 左键单击 –> 选中或确定操作 按住左键 –> 选中区域内所有组件 左键双击&#xff0c;可以选择以特定操作模式和窗口类型进入对应组件的下一层一般我是ed…

Winform从入门到精通(36)—ColorDialog(史上最全)更新中

前言 当我们需要设置某个控件的颜色时,并且需要弹出一个可以选择颜色的对话框时,这时候就需要使用ColorDialog 一、属性 1、AllowFullOpen 该属性用于启用或者禁用“自定义颜色按钮”,该属性为true时,可以自定义颜色 2、AnyColor 实际测试该属性没什么作用 3、Colo…

请求与相应

从容器到Servlet 前面我们介绍了JSP的内置对象和Servlet的相关知识&#xff0c; 以及如何部署和开发一个Servlet。但是&#xff0c; 并没有详细介绍如何将Servlet与JSP结合起来使用。Web容器是JSP唯一可以识别的HTTP服务器&#xff0c; 所以必须了解Web容器如何生成请求和响应…

来上海一个月的记录、思考和感悟

作者 | gongyouliu 编辑 | gongyouliu 从4月3号早上来上海&#xff0c;到今天差不多整整一个月了&#xff0c;也是自己正式从杭州离职创业&#xff08;我更愿意称之为自由职业者&#xff0c;毕竟我没有招聘全职员工&#xff0c;有两个朋友业余时间在帮我&#xff09;的第一个月…

SAP UI5 之Bootstrap(引导)笔记二

文章目录 Setting up Visual Studio Code for UI5 development1.0 官网 Walkthrough学习-Bootstrap 引导加载1.0.1 在 index.html中新增script标签1.0.2 在webapp 下面新增index.js文件1.0.3启动UI5的服务 Setting up Visual Studio Code for UI5 development 学习链接 Setti…

如何正确部署Redisearch和Rejson(附*.so文件免费下载)

1 缘起 项目需要。 最近的一个项目需要做文本搜索,技术选型:Redis的两个组件Redisearch和ReJSON。 Redisearch和ReJSON是Redis的两个组件: RediSearch为Redis提供查询、二次索引和全文搜索。使用RediSearch,首先要在Redis数据上声明索引。然后使用RediSearch查询语言来查…

【电子通识】颜色的困惑:什么是国际通用Panone(潘通)

Pantone 是世界知名的色彩权威机构&#xff0c;也是色彩系统的供应商&#xff0c;为许多行业提供专业色彩选择。在 Pantone 之前&#xff0c;每个印刷公司都有自己的色彩指南。比如都是“黄色”&#xff0c;但由于印刷方式有所不同&#xff08;具体取决于每个油墨公司如何解释该…

学习之-Mysql Sql 优化之 Explain

在开发中&#xff0c;往往遇到一些慢查询语句&#xff0c; 我们需要对慢查询进行优化。Explain工具就是用来分析某个慢查询执行情况的工具。通过在select 语句前加上explain 关键字&#xff0c;然后执行就会得到某个sql 执行计划信息&#xff0c;通过分析执行计划&#xff0c;我…