容器中的operator[]注意事项

news2024/12/23 17:39:21

首先看一张表格,支持operator[]的容器包括stringarrayvectordequemapunordered_map,顺序容器和关联容器的operator[]不太一致。
在这里插入图片描述

string中的operator[]

pos < size()时返回到位于指定位置pos的字符的引用,或在pos == size()时返回到拥有值CharT()的字符(空字符)的引用。不进行边界检查。
如果 pos > size(),那么行为未定义。

int main() {
    std::string const e("Exemplar");
    for (unsigned i = e.length() - 1; i != 0; i /= 2)
        std::cout << e[i];
    std::cout << '\n';
 
    const char* c = &e[0];
    std::cout << c << '\n'; // 作为 C 字符串打印
    // 将 s 的最后一个字符改成 'y'
    std::string s("Exemplar ");
    s[s.size() - 1] = 'y';
    std::cout << s << '\n';
    return 0;
}

运行结果

rmx
Exemplar
Exemplary

Array中的operator[]

返回位于指定位置 pos 的元素的引用。不进行边界检查。
不同于std::map::operator[]此运算符决不插入新元素到容器。通过此运算符访问不存在的元素是未定义行为。

#include <iostream>
#include <map>
#include <string>
#include <string_view>
#include <vector>
#include <array>

using namespace std;
int main() {
    std::array<int,4> numbers {2, 4, 6, 8};

    std::cout << "Second element: " << numbers[1] << '\n';
 
    numbers[0] = 5;
 
    std::cout << "All numbers:";
    for (auto i : numbers) {
        std::cout << ' ' << i;
    }
    std::cout << '\n';
    return 0;
}

运行结果

Second element: 4
All numbers: 5 4 6 8

vector中的operator[]

返回位于指定位置 pos 的元素的引用。不进行边界检查。

#include <vector>
#include <iostream>
 
int main()
{
    std::vector<int> numbers {2, 4, 6, 8};
 
    std::cout << "Second element: " << numbers[1] << '\n';
 
    numbers[0] = 5;
 
    std::cout << "All numbers:";
    for (auto i : numbers) {
        std::cout << ' ' << i;
    }
    std::cout << '\n';
}

运行结果

Second element: 4
All numbers: 5 4 6 8

deque中的operator[]

reference       operator[]( size_type pos );	
const_reference operator[]( size_type pos ) const;

返回位于指定位置 pos 的元素的引用。不进行边界检查。

#include <deque>
#include <iostream>
 
int main()
{
    std::deque<int> numbers {2, 4, 6, 8};
 
    std::cout << "Second element: " << numbers[1] << '\n';
 
    numbers[0] = 5;
 
    std::cout << "All numbers:";
    for (auto i : numbers) {
        std::cout << ' ' << i;
    }
    std::cout << '\n';
}

运行结果

Second element: 4
All numbers: 5 4 6 8

map中的operator[]

T& operator[]( const Key& key );(1) 	
T& operator[]( Key&& key );(2) 	(C++11)

返回到映射到等于key的键的值的引用,这种键不存在的情况下就会进行插入。

  1.  (`C++11 `前) 在键不存在的情况下插入` value_type(key, T())`
    
  • key_type 必须符合可复制构造 (CopyConstructible) 的要求。
  • mapped_type 必须符合可复制构造 (CopyConstructible) 和 可默认构造 (DefaultConstructible) 的要求。
    如果进行插入,那么值初始化被映射值(对类类型为默认构造,否则为零初始化)并返回到它的引用
  1. c++11
  • 在键不存在的情况下插入从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) 。
  1. 在键不存在的情况下插入从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) 。

参数

key - 要寻找的元素键

返回值

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

异常

如果任何操作抛出异常,那么插入无效果。

注解

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

然而,已知一个实现(libc++)通过两个分离的分配器construct()调用构造key_type mapped_type 对象,可认为如发布时的标准所要求,而非原位构造 value_type 对象。
operator[] const,因为它会在键不存在时插入键。如果此行为非所欲或容器为 const,那么可以使用 at()
insert_or_assign() 返回的信息多于 operator[],而且不要求mapped_type可默认构造。(C++17 起)

#include <iostream>
#include <map>
#include <string>

auto print = [](auto const comment, auto const& map) {
    std::cout << comment << "{";
    for (const auto& pair : map)
        std::cout << "{" << pair.first << ": " << pair.second << "}";
    std::cout << "}\n";
};

int main() {
    std::map<char, int> letter_counts{{'a', 27}, {'b', 3}, {'c', 1}};

    print("letter_counts 初始状态下包含:", letter_counts);

    letter_counts['b'] = 42;  // 更新既存值
    letter_counts['x'] = 9;   // 插入新值

    print("修改后它包含:", letter_counts);

    // 统计每个单词的出现次数
    // (首次调用 operator[] 会初始化计数为零)
    std::map<std::string, int> word_map;
    for (const auto& w : {"this", "sentence", "is", "not", "a", "sentence",
                          "this", "sentence", "is", "a", "hoax"})
        ++word_map[w];
    word_map["that"];  // 插入对 {"that", 0}

    for (const auto& [word, count] : word_map)
        std::cout << "单词 '" << word << "' 出现 " << count << "次\n";
}

运行结果,注意这个 word_map["that"]; // 插入对 {"that", 0} 是插入了一个map值

letter_counts 初始状态下包含:{{a: 27}{b: 3}{c: 1}}
修改后它包含:{{a: 27}{b: 42}{c: 1}{x: 9}}
单词 'a' 出现 2次
单词 'hoax' 出现 1次
单词 'is' 出现 2次
单词 'not' 出现 1次
单词 'sentence' 出现 3次
单词 'that' 出现 0次
单词 'this' 出现 2

unordered_map中的operator[]

T& operator[]( const Key& key );(1) 	(C++11)
T& operator[]( Key&& key );(2) 	(C++11)

返回到映射到等于 key 的键的值的引用,这种键不存在的情况下就会进行插入。

#include <iostream>
#include <string>
#include <unordered_map>
 
auto print = [](auto const comment, auto const& map)
{
    std::cout << comment << "{";
    for (const auto &pair : map)
        std::cout << "{" << pair.first << ": " << pair.second << "}";
    std::cout << "}\n";
};
 
int main()
{
    std::unordered_map<char, int> letter_counts{{'a', 27}, {'b', 3}, {'c', 1}};
 
    print("letter_counts 初始状态下包含:", letter_counts);
 
    letter_counts['b'] = 42; // 更新既存值
    letter_counts['x'] = 9;  // 插入新值
 
    print("修改后它包含:", letter_counts);
 
    // 统计每个单词的出现次数
    // (首次调用 operator[] 会初始化计数为零)
    std::unordered_map<std::string, int>  word_map;
    for (const auto& w : {"this", "sentence", "is", "not", "a", "sentence",
                          "this", "sentence", "is", "a", "hoax"})
        ++word_map[w];
    word_map["that"]; // 插入对 {"that", 0}
 
    for (const auto& [word, count] : word_map)
        std::cout << "单词 '" << word << "' 出现 " << count << "次\n";
}

运行结果

letter_counts 初始状态下包含:{{c: 1}{b: 3}{a: 27}}
修改后它包含:{{x: 9}{c: 1}{b: 42}{a: 27}}
单词 'a' 出现 2次
单词 'not' 出现 1次
单词 'is' 出现 2次
单词 'that' 出现 0次
单词 'hoax' 出现 1次
单词 'sentence' 出现 3次
单词 'this' 出现 2

参考

官网容器

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

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

相关文章

信息安全数学基础笔记

三个数学难题: 群的定义: 满足乘法结合律&#xff0c;有单位元&#xff0c;逆元即为群&#xff0c;如果同时满足交换律则为交换群 满足乘法结合律&#xff0c;有单位元即为半群&#xff0c;如果同时满足交换律则为交换半群 希尔密码: 其中加密矩阵为n阶一般线性群&#xff0c;…

视频与音频一键同步嘴型数字人ai工具分享

在ai发展的今天,各种虚拟主播工具层出不穷,我们在选择ai工具的适合往往陷入一个使用陷阱。 比如, 看演示视频效果非常不错,自己去用却跟智障一样的。出现这种情况,我们首先不去评价这个工具的好用,我们得分析别人使用的前置条件。 大部分前置条件都是大量的训练数据, …

进程通信和信号量

1.进程通信 管道&#xff1a;包括无名管道(pipe)和命名管道(named pipe),无名管道可用于具有父进程和子进程之间的通信。命名管道除具有管道所具有的所有功能外&#xff0c;它还允许无亲缘关系进程间的通信。消息队列&#xff1a;进程可以向队列中添加消息&#xff0c;其他进程…

代码量原地缩减50%,这个Java工具类库太香了

Guava是google公司开发的一款Java类库扩展工具包&#xff0c;内含了丰富的API&#xff0c;涵盖了集合、缓存、并发、I/O等多个方面。使用这些API一方面可以简化我们代码&#xff0c;使代码更为优雅&#xff0c;另一方面它补充了很多jdk中没有的功能&#xff0c;能让我们开发中更…

长沙银行财报启示录:“生态引擎”如何突破“低维竞争”?

众多行业当中&#xff0c;银行业一直被当做“经济晴雨表”。 今年以来&#xff0c;中国经济开启回暖模式。尤其是在前不久的五一假期&#xff0c;各地消费回暖&#xff0c;释放出经济持续向好的积极信号。此时&#xff0c;也正是各家银行发布成绩单的财报季&#xff0c;能发现…

OPC UA Client接口库

OPC UA库秉承简单、易用、可靠的设计理念&#xff0c;只需少量接口即可实现所需功能&#xff0c;同时使用者无需考虑多线程&#xff0c;时序等问题 1. 拷贝代码文件 将 \JngOpcUaClient\JngOpcUaClient\Input\ 文件夹拷贝到项目中&#xff0c;添加到项目。 2. 拷贝dll库及Secu…

ES+Redis+MySQL,高可用架构设计方案

ES高可用方案 1. ES双中心主备集群架构 全平台所有体系的会员总量是十多亿。在这么大的数据体量下&#xff0c;业务线的查询维度也比较复杂。有的业务线基于手机号&#xff0c;有的基于微信unionid&#xff0c;也有的基于卡号等查询会员信息。这么大的数据量&#xff0c;又有…

Java基础(40)反射机制

Java反射机制是 Java 语言的一个重要特性。先了解两个概念&#xff0c;编译期和运行期。编译期是指把源码交给编译器编译成计算机可以执行的文件的过程。在 Java 中也就是把 Java 代码编成 class 文件的过程。编译期只是做了一些翻译功能&#xff0c;并没有把代码放在内存中运行…

平平无奇的Python为什么能一跃成为世界排名第一的语言

一、前言 本文将结合个人经历为各位同学客观的分析是否有学习Python的必要、Python适合谁学、为什么要学&#xff0c;希望能够给看到此文章的同学一点建议&#xff0c;树立学习目标&#xff0c;让学习有结果。 读完后&#xff0c;相信你一定能够有所收获。 二、简述个人经历…

Word控件Spire.Doc 【文本框】教程(4):如何将图像插入文本框

Spire.Doc for .NET是一款专门对 Word 文档进行操作的 .NET 类库。在于帮助开发人员无需安装 Microsoft Word情况下&#xff0c;轻松快捷高效地创建、编辑、转换和打印 Microsoft Word 文档。拥有近10年专业开发经验Spire系列办公文档开发工具&#xff0c;专注于创建、编辑、转…

swift闭包底层本质

swift学习笔记 闭包底层原理 1、函数赋值给一个变量 func getFn(_ a: Int) -> Int {return a 1 }let funcVar getFn当在把一个函数赋值给一个变量funcVar的时候&#xff0c;funcVar变量会存储两个东西 funcVar总共占用16个字节前八个字节存储着getFn的函数地址后八个字…

浅聊一下NTP

浅聊一下NTP 仅了解&#xff0c;没实践过NTP 文章目录 浅聊一下NTP1.什么是NTP2.基本原理3.工作模式1.单播服务器/客户端模式2.对等体模式3.广播模式4.组播模式 4.NTP数据报文 1.什么是NTP 网络时间协议NTP&#xff08;Network Time Protocol&#xff09;是TCP/IP协议族里面…

PowerShell系列(三):PowerShell发展历程梳理

目录 1、PowerShell 1.0 版本特性 2、PowerShell 2.0 版本特性 3、PowerShell 3.0 版本特性 4、PowerShell 4.0 版本特性 5、PowerShell 5.0 版本特性 6、PowerShell 5.1 版本特性 7、PowerShell6.0 Core 版本特性 8、PowerShell7.0 Core 版本特性 今天给大家聊…

openAI图像生成开发文档

图像生成 了解如何使用我们的 DALLE 型号 介绍 图像 API 提供了三种与图像交互的方法&#xff1a; 根据文本提示从头开始创建图像根据新的文本提示创建现有图像的编辑创建现有图像的变体 本指南介绍了使用这三个 API 终结点的基础知识以及有用的代码示例。要了解它们的实际…

海外网红营销vs国内网红营销:2023年市场洞察与策略差异

随着互联网和社交媒体的迅猛发展&#xff0c;网红营销已经成为一种炙手可热的推广方式。无论是国内还是海外&#xff0c;网红营销都在不断演变和创新&#xff0c;以满足广告主和品牌的需求。然而&#xff0c;海外网红营销和国内网红营销之间存在一些显著的区别。本文Nox聚星将和…

第三章 哈希表

目录 一、有效的字母异位词1.1 赎金信1.2 字符异位词分组1.3 找到字符串中所有字母异位词 二、两个数组的交集2.1 两个数组的交集 II 三、快乐数四、两数之和五、四数相加 II六、三数之和七、四数之和 哈希解决问题一般有三种数据结构供选择&#xff1a; 数组map&#xff08;映…

图解LeetCode——234. 回文链表

一、题目 给你一个单链表的头节点 head &#xff0c;请你判断该链表是否为回文链表。如果是&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 二、示例 2.1> 示例 1&#xff1a; 【输入】head [1,2,2,1] 【输出】true 2.2> 示例 2&#xff1a; 【输…

[Android Studio Tool]在Android Studio项目中如何使用CSV文件

文章目录 在Android Studio项目中如何使用CSV文件1. 前情提要&#xff1a;CSV文件的准备2. CSV文件在安卓项目一般存放在什么位置&#xff1f;3. Android Studio处理CSV文件的常用插件&#xff1f;4. 怎么调整Android Studio中对GBK编码的CSV文件的处理&#xff1f;以下是一个代…

就业内推 | 国企招运维工程师,红帽认证、华为认证优先

01 厦门中盾安信科技有限公司 &#x1f537;招聘岗位&#xff1a;应用运维工程师&#xff08;中级&#xff09; &#x1f537;职责描述&#xff1a; 1、负责平台应用系统的安装、配置、日常巡检、维护、故障的处理&#xff1b; 2、负责平台服务相关应用的部署、配置、日常巡检…

Java面试知识点(全)- Java IO知识点详细

Java面试知识点(全) 导航&#xff1a; https://nanxiang.blog.csdn.net/article/details/130640392 注&#xff1a;随时更新 从数据传输方式理解IO流 从数据传输方式或者说是运输方式角度看&#xff0c;可以将 IO 类分为: 字节流, 字节流读取单个字节&#xff0c;字符流读取单…