c++ 11标准模板(STL) std::map(四)

news2024/12/22 14:33:41

定义于头文件<map>

template<

    class Key,
    class T,
    class Compare = std::less<Key>,
    class Allocator = std::allocator<std::pair<const Key, T> >

> class map;
(1)
namespace pmr {

    template <class Key, class T, class Compare = std::less<Key>>
    using map = std::map<Key, T, Compare,
                         std::pmr::polymorphic_allocator<std::pair<const Key,T>>>

}
(2)(C++17 起)

std::map 是有序键值对容器,它的元素的键是唯一的。用比较函数 Compare 排序键。搜索、移除和插入操作拥有对数复杂度。 map 通常实现为红黑树。

在每个标准库使用比较 (Compare) 概念的位置,以等价关系检验唯一性。不精确而言,若二个对象 ab 互相比较不小于对方 : !comp(a, b) && !comp(b, a) ,则认为它们等价(非唯一)。

std::map 满足容器 (Container) 、具分配器容器 (AllocatorAwareContainer) 、关联容器 (AssociativeContainer) 和可逆容器 (ReversibleContainer) 的要求。


元素访问

访问指定的元素,同时进行越界检查

std::map<Key,T,Compare,Allocator>::at

T& at( const Key& key );

(1)(C++11 起)

const T& at( const Key& key ) const;

(2)(C++11 起)

返回到拥有等于 key 的关键的元素被映射值的引用。若无这种元素,则抛出 std::out_of_range 类型异常。

参数

key-要找到的元素的关键

返回值

到请求元素的被映射值的引用

异常

若容器无拥有指定 key 的元素则为 std::out_of_range

复杂度

与容器大小成对数。

访问或插入指定的元素

std::map<Key,T,Compare,Allocator>::operator[]

T& operator[]( const Key& key );

(1)

T& operator[]( Key&& key );

(2)(C++11 起)

返回到映射到等于 key 的关键的值的引用,若这种关键不存在则进行插入。

1) 若关键不存在则插入 value_type(key, T()) 。此函数等价于 return insert(std::make_pair(key, T())).first->second;
- key_type 必须满足可复制构造 (CopyConstructible) 的要求。
- mapped_type 必须满足可复制构造 (CopyConstructible) 和 可默认构造 (DefaultConstructible) 的要求。
若进行插入,则值初始化被映射值(对类类型为默认构造,否则为零初始化)并返回到它的引用。
(C++11 前)
1) 若关键不存在,则插入从 std::piecewise_construct, std::forward_as_tuple(key), std::tuple<>() 原位构造的 value_type 对象。此函数等价于 return this->try_emplace(key).first->second; 。 (C++17 起)
使用默认分配器时,这导致从 key 复制构造关键,并值初始化被映射值。
- value_type 必须从 std::piecewise_construct, std::forward_as_tuple(key), std::tuple<>() 可就位构造 (EmplaceConstructible) 。使用默认分配器时,这表明 key_type 必须可复制构造 (CopyConstructible) 而 mapped_type 必须可默认构造 (DefaultConstructible) 。
2) 若关键不存在,则插入从 std::piecewise_construct, std::forward_as_tuple(std::move(key)), std::tuple<>() 原位构造的 value_type 对象。此函数等价于 return this->try_emplace(std::move(key)).first->second; 。 (C++17 起)
使用默认分配器时,这导致从 key 移动构造关键,并值初始化被映射值。
- value_type 必须从 std::piecewise_construct, std::forward_as_tuple(std::move(key)), std::tuple<>() 可就位构造 (EmplaceConstructible) 。使用默认分配器时,这表明 key_type 必须可移动构造 (MoveConstructible) mapped_type 必须可默认构造 (DefaultConstructible) 。
(C++11 起)

没有迭代器或引用被非法化。

参数

key-要寻找的元素关键

返回值

若不存在拥有关键 key 的元素,则为到新元素被映射值的引用。否则为到既存的关键等价于 key 的元素的被映射值的引用。

异常

若任何操作抛出异常,则插入无效果。

复杂度

与容器大小成对数。

注意

出版的 C++11 和 C++14 标准中,指定此函数要求 mapped_type可默认插入 (DefaultInsertable) 且 key_type可复制插入 (CopyInsertable) 或可移动插入 (MoveInsertable) 到 *this 。此规定有缺陷并为 LWG 问题 2469 所修复,而上面的描述合并了该问题的解决方案。

然而,已知一个实现( libc++ )通过二个分离的分配器 construct() 调用构造 key_typemapped_type 对象,可认为如发布时的标准所要求,而非原位构造 value_type 对象。

operator[] 非 const ,因为若不关键不存在则它插入关键。若此行为非所欲或容器为 const ,则可用 at()

insert_or_assign() 返回的信息多于 operator[] ,而且不要求 mapped_type 可默认构造。

(C++17 起)

 

调用示例

#include <iostream>
#include <forward_list>
#include <string>
#include <iterator>
#include <algorithm>
#include <functional>
#include <map>
#include <time.h>

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

struct myCompare
{
    bool operator()(const int &a, const int &b)
    {
        return a < b;
    }
};

std::ostream &operator<<(std::ostream &os, const Cell &cell)
{
    os << "{" << cell.x << "," << cell.y << "}";
    return os;
}

std::ostream &operator<<(std::ostream &os, const std::pair<const int, Cell> &pCell)
{
    os << pCell.first << "-" << pCell.second;
    return os;
}

int main()
{
    auto genKey = []()
    {
        return std::rand() % 10 + 100;
    };

    auto generate = []()
    {
        int n = std::rand() % 10 + 100;
        Cell cell{n, n};
        return cell;
    };

    std::map<int, Cell> map1;
    for (size_t index = 0; index < 5; index++)
    {
        map1.insert({genKey(), generate()});
    }
    std::cout << "map1:    ";
    std::copy(map1.begin(), map1.end(),
              std::ostream_iterator<std::pair<const int, Cell>>(std::cout, " "));
    std::cout << std::endl;
    std::cout << std::endl;

    //返回到拥有等于 key 的关键的元素被映射值的引用。
    //若无这种元素,则抛出 std::out_of_range 类型异常。
    std::cout << "T& at( const Key& key );" << std::endl;
    for (const std::pair<int, Cell> it : map1)
    {
        Cell cell = generate();
        map1.at(it.first) = cell;
        std::cout << "map1.at( " << it.first << " ) = " << cell << std::endl;
    }
    std::cout << std::endl;

    std::cout << "const T& at( const Key& key ) const;" << std::endl;
    for (const std::pair<int, Cell> it : map1)
    {
        std::cout << "map1.at( " << it.first << " ) : " << map1.at(it.first) << std::endl;
    }
    std::cout << std::endl;
    std::cout << std::endl;

    //返回到映射到等于 key 的关键的值的引用,若这种关键不存在则进行插入。
    std::cout << "T& operator[]( const Key& key );" << std::endl;
    std::map<int, Cell> map2;
    while (map2.size() < 5)
    {
        //1) 若关键不存在则插入 value_type(key, T()) 。
        //此函数等价于 return insert(std::make_pair(key, T())).first->second;
        map2[genKey()] = generate();
    }
    std::cout << "map2:    ";
    std::copy(map2.begin(), map2.end(),
              std::ostream_iterator<std::pair<const int, Cell>>(std::cout, " "));
    std::cout << std::endl;
    std::cout << std::endl;

    std::cout << "T& operator[]( Key&& key );" << std::endl;
    std::map<int, Cell> map3;
    while (map3.size() < 5)
    {
        //1) 若关键不存在则插入 value_type(key, T()) 。
        //此函数等价于 return insert(std::make_pair(key, T())).first->second;
        map3[std::move(genKey())] = generate();
    }
    std::cout << "map3:    ";
    std::copy(map3.begin(), map3.end(),
              std::ostream_iterator<std::pair<const int, Cell>>(std::cout, " "));
    std::cout << std::endl;
    std::cout << std::endl;

    return 0;
}

输出

 

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

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

相关文章

150套开发板免费送!还有5G手机拿?米尔RZ/G2L开发板创意秀

人间最美五月天 不负韶华不负卿 米尔又来送板子了 不是3套&#xff0c;也不是4套 150套米尔RZ/G2L开发板 送&#xff01;免费&#xff01;板卡不回收&#xff01; 这是什么样的有奖活动&#xff1f; 米尔RZ/G2L开发板创意秀 为感谢广大客户一直以来的支持&#xff0c;推动…

15 个非常流行的VsCode插件,让你的编码效率倍增!

VS Code已经成为了最受欢迎的代码编辑器之一。 它的简洁性、易用性和可扩展性使得它成为了许多开发者的首选。 而在VS Code中&#xff0c;插件是其最大的卖点之一。 通过安装插件&#xff0c;你可以将VS Code打造成一个功能强大的开发环境&#xff0c;从而提高你的编码效率。…

【2023A题】电采暖负荷参与电力系统功率调节的技术经济分析(思路、代码)

目录 &#x1f4a5;1 概述 &#x1f4da;2 Matlab代码实现 &#x1f389;3 参考文献 &#x1f308;4 运行结果 &#x1f4a5;1 概述 建设以新能源为主体的新型电力系统是应对全球气候变化挑战的重要举措。高比例新能源接入导致电力系统调节能力稀缺&#xff0c;亟需开发新的调…

Node版本管理器nvm的安装与使用

前言&#xff1a; 多项目新旧项目管理的时候&#xff0c;往往与依赖不同的node版本&#xff0c;不同的版本对其他依赖的安装有一定的影响&#xff0c;因此我们需要对node的版本进行方便快捷管理和切换&#xff0c;如果直接卸载重装对应版本&#xff0c;切换项目再次卸载重装明显…

word打印为pdf去掉批注和修订记录

对于这个问题某乎上充斥着垃圾回答&#xff0c;大多引流到自家开发的pdf产品上。其实背后的方法都是一样的&#xff0c;就是关掉批注&#xff0c;用word自带的功能就能解决&#xff0c;凡是word编辑软件都有类似功能 直接用word打印为pdf后的效果 下图为打印出来的pdf文件&…

杜绝开源依赖风险,许可证扫描让高效合规「两不误」

目录 开源许可证及其常见类型 开源许可证扫描是软件研发过程中&#xff0c;不可或缺的工具 极狐GitLab 开源许可证扫描的优势与应用 Step 1&#xff1a;启用及设置许可证策略 Step 2&#xff1a;自动创建策略文件存放项目 Step 3&#xff1a;查看许可证合规情况 Step 4&…

<Linux开发>驱动开发 -之-gpio子系统

&#xff1c;Linux开发&#xff1e;驱动开发 -之-gpio子系统 交叉编译环境搭建&#xff1a; &#xff1c;Linux开发&#xff1e; linux开发工具-之-交叉编译环境搭建 uboot移植可参考以下&#xff1a; &#xff1c;Linux开发&#xff1e; -之-系统移植 uboot移植过程详细记录&…

vue实现倒计时功能

vue实现倒计时功能 首先我们需要一个 Vue. js的函数&#xff0c;这个函数用于实现倒计时&#xff0c;这里我们采用 vue. js的 import来实现&#xff0c;这是 vue. js的一个特殊功能&#xff0c;将函数调用的参数以列表的形式加入到函数中&#xff0c;当在函数执行完后返回结果。…

Java基础--->IO流(2)【常见IO模型】

文章目录 计算机角度IO操作系统IO常见的IO模型Java 中 3 种常见 IO 模型BIO&#xff08;BlockingI/O&#xff09;【同步阻塞IO】NIO&#xff08;Non-blocking/New I/O&#xff09;【非阻塞IO】IO多路复用AIO&#xff08;Asynchronous I/O&#xff09;【异步IO】 计算机角度IO 根…

进攻中型SUV,蔚来/小鹏的智能化「满配」能否撬动需求

251.29万辆&#xff0c;这是2022年中国市场&#xff08;不含进出口&#xff09;乘用车中型SUV交出的答卷&#xff0c;交付量仅次于紧凑型SUV&#xff0c;排名细分市场第二。在这份成绩单中&#xff0c;有几个数字特别醒目。 1、31.64万辆&#xff0c;这是排名这个细分市场交付量…

chatgpt赋能python:Python交易股票:掌握交易技巧,开启财富增长之路

Python 交易股票&#xff1a;掌握交易技巧&#xff0c;开启财富增长之路 股票市场一直以来都是吸引人们收益的地方&#xff0c;不断变化的市场行情也让每一位投资者都不得不面对各种风险。然而&#xff0c;如果您懂得运用好 Python 来交易股票&#xff0c;就能够更好地理解市场…

【软考-中级】系统集成项目管理工程师 【14 采购管理】

持续更新。。。。。。。。。。。。。。。 【第十四章】采购管理 2 分 14.1采购管理的相关概念和主要过程14.1.1 概念和术语14.1.2 采购管理的主要过程 14.2编制采购管理计划14.2.1编制采购计划的输入、输出14.2.2用于编制采购计划过程的技术和方法14.2.3工作说明书 历年真题202…

小程序外包开发上线流程

小程序有非常多的优势&#xff0c;无需下载安装、使用方便、开发成本低、覆盖广泛、轻量级、方便推广&#xff0c;这些特点使得小程序非常适合场景不太复杂的场合&#xff0c;这些年出现了大量的小程序。今天和大家分享一下小程序的一些特点和上线流程&#xff0c;希望对大家有…

C#,码海拾贝(21)——“全选主元高斯消去法“求解“线性方程组“的C#源代码,《C#数值计算算法编程》源代码升级改进版

using System; namespace Zhou.CSharp.Algorithm { /// <summary> /// 求解线性方程组的类 LEquations /// 原作 周长发 /// 改编 深度混淆 /// </summary> public static class LEquations { /// <summary> /…

mysql倒库操作遇到的问题

背景&#xff1a;本地windows 10安装了mysql数据库后&#xff0c;需要把远程库的表结构和数据全部导入进来。 操作&#xff1a;导出数据库&#xff0c;导入数据库。 第一步&#xff1a;导出数据库 使用dump命令即可。 登陆mysql数据库 mysql -hhost --default-character-s…

springboot整合ueditor有源码

在项目用到ueditor插件来编辑信息&#xff0c;初次接触&#xff0c;遇到各种问题&#xff0c;到目前为止&#xff0c;也只是基本实现了功能&#xff0c;简单记录一下过程&#xff0c;希望对初次使用ueditor的朋友们有所帮助。 ueditor就不介绍了&#xff0c;或对ueditor还不了…

尝试 python flink

引入pyflink库 启动anaconda的终端窗口 执行命令 pip install apache-flink1.13.2 等待安装flink相关库

< ElementUi组件库: el-progress 进度条Bug及样式调整 >

ElementUi组件库&#xff1a; el-progress 进度条Bug及样式调整 &#x1f449; 前言&#x1f449; 一、实现原理> 修改 el-progress 进度条样式 及 渐变进度条样式 &#x1f449; 二、案例代码&#xff08;前言效果图案例&#xff09;> HTML代码> CSS代码 &#x1f44…

详细解读Diffuser DreamBooth代码

Diffusion Models专栏文章汇总:入门与实战 前言:之前的博客《如何定制属于自己的stable diffusion?Dreambooth原理详解和代码实战》详细解读了dreambooth,不过那篇博客的代码讲解部分主要基于mmagic,不过瘾。这篇博客讲解一下diffuser的drembooth的部分。 目录 参数详解…

C#,码海拾贝(24)——求解“复系数方程组”的“全选主元高斯-约当消去法”之C#源代码,《C#数值计算算法编程》源代码升级改进版

using System; namespace Zhou.CSharp.Algorithm { /// <summary> /// 求解线性方程组的类 LEquations /// 原作 周长发 /// 改编 深度混淆 /// </summary> public static partial class LEquations { /// <summary> …