为什么 QList::at() 不检查索引是否存在并返回只读值?

2024-01-08

这个问题更多的是一种询问,而不是实际寻求问题的解决方案。

QList::at()不仅不检查索引是否越界,而且还返回const因此它只能用于read-only设想:

const T &QList::at(int i) const

返回列表中索引位置 i 处的项目。我必须是一个有效的 列表中的索引位置(即 0

这个函数非常快(恒定时间)。

我刚刚发现了这些特殊的实现细节QList在尝试为列表中的元素分配新值时,我想知道是否有这样做的理由。

不检查索引有效性

In C++ STL如果我们采取std::array or std::vector(我不采取std::list因为它没有std::list::at()完全)我们有以下内容:

std::向量::at

该函数自动检查 n 是否在向量中有效元素的范围内,如果不在则抛出 out_of_range 异常

起初我以为不包括检查是为了确保“这个功能非常快(恒定时间)”。但是在查看了实施之后QList我不得不说,即使包括检查,也能保证恒定的时间(并且高速)。

检查越界需要两件事(据我所知):

  • 检查给定索引是否 O(1)如果我们使用一些古怪的符号)。显然我们不能有负索引(我们可以Python但它还有另一个含义;))
  • 检查给定索引是否QList::size()- 恒定的时间也存在于此QList::size()实施的是:

    inline int size() const Q_DECL_NOTHROW { return d->end - d->begin; }
    

    这又是O(1)(如果我没记错的话)因为这两个值都存储在QList::d参数是一个指针

    struct Data {
      QtPrivate::RefCount ref;
      int alloc, begin, end;
      void *array[1];
    };
    

    因此,访问这些并计算它们的差异不会对性能造成太大影响(显然它有一些轻微的影响,因为它引入了一些访问和算术操作,再加上由于堆栈内部的跳转而备份和恢复堆栈)QList::size()功能)。

那么为什么要放弃对索引有效性的检查呢?性能影响真的那么大吗?

返回只读值

通过这样做QList::at()函数提供了一个隐藏的和(omho)不是很有用的功能,这使得使用它和QList::[]更令人困惑。还有C++ STL相当于std::vector and std::array允许使用此函数分配新值。


有“3”种方法可以从索引中访问项目QList:

const T& QList::at(int) const
T& QList::operator[](int)
const T& QList::operator[](int) const

如果您查看文档,您会发现最后一个很简单:

与 at() 相同。该函数以恒定时间运行。

So we are left with the first one (at) and the non-const operator[]. Here is the problem, the documentation of the second one tells you that1:

如果在当前正在共享的列表上调用此函数,它将触发所有元素的副本。否则,该函数将在恒定时间内运行。如果您不想修改列表,您应该使用QList::at().

Note:这也适用于QVector:

请注意,使用非常量运算符可能会导致QVector进行深复制。

1 For QList, this is actually only true for Qt 5 http://doc.qt.io/qt-5/qlist.html#operator-5b-5d, not for Qt 4 http://doc.qt.io/qt-4.8/qlist.html#operator-5b-5d (at least in the documentation), but for QVector it was already true for Qt 4 http://doc.qt.io/qt-4.8/qvector.html#operator-5b-5d, so the .at method was probably made consistent between all Qt containers.

这意味着您不能使用operator[]直接在非常量共享上QList或非常量QVector,你需要做类似的事情:

QList<T> &mySharedQList = ...;
const QList<T> &myConstRef = mySharedQList;
myConstRef[0]; // Only ways not to copy the original QList

我的猜测是,这样做的目的是.at就是为你提供一个方法保证恒定的访问时间,无论什么QList or QVector是(其中operator[]不保证)。对于标准库容器,您不需要这样的方法,因为非常量operator[]已经保证在恒定时间内运行(它们永远不会复制)。

关于对索引的检查,这可能是为了保持operator[]因为,不像std::vector,你可能想使用.at任何地方你只需要读取数据。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 QList::at() 不检查索引是否存在并返回只读值? 的相关文章

  • Exit() 时是否调用基本对象析构函数?

    我意识到这个问题已经出现过几次 但我试图获得上述问题的明确答案 但我不断遇到相互矛盾的信息 我需要知道的是 当我使用 exit 时 基本类对象是否被破坏 我知道需要删除动态内存 但我的意思更像是 include
  • 在 HKCR 中创建新密钥有效,但不起作用

    我有以下代码 它返回 成功 但使用两种不同的工具使用搜索字符串 3BDAAC43 E734 11D5 93AF 00105A990292 搜索注册表不会产生任何结果 RegistryKey RK Registry ClassesRoot C
  • 尝试了解使用服务打开对话框

    我已经阅读了有关使用 mvvm 模式打开对话框的讨论 我看过几个使用服务的示例 但我不明白所有部分如何组合在一起 我发布这个问题寻求指导 以了解我应该阅读哪些内容 以更好地理解我所缺少的内容 我将在下面发布我所拥有的内容 它确实有效 但从我
  • 转换 const void*

    我有一个函数返回一个const void 我想用它的信息作为char 我可以将它投射为 C 风格的罚款 char variable但是当我尝试使用reinterpret cast like reinterpret cast
  • 如何在类文件中使用 Url.Action() ?

    如何在 MVC 项目的类文件中使用 Url Action Like namespace 3harf public class myFunction public static void CheckUserAdminPanelPermissi
  • 如何将 SOLID 原则应用到现有项目中

    我对这个问题的主观性表示歉意 但我有点卡住了 我希望之前处理过这个问题的人能够提供一些指导和建议 我有 现在已经成为 一个用 C 2 0 编写的非常大的 RESTful API 项目 并且我的一些类已经变得巨大 我的主要 API 类就是一个
  • 如何将 .txt 文件中的数据转换为 xml? C#

    我在一个文本文件中有数千行数据 我想通过将其转换为更容易搜索的内容来轻松搜索 我希望 XML 或其他类型的大型数据结构 尽管我不确定它是否是最好的对于我的想法 每行的数据如下所示 第 31 册 托马斯 乔治 32 34 154 每本书都不是
  • 处理右值时的 insert 与 emplace

    std string myString std unordered set
  • 在 C# 中检查 PowerShell 执行策略的最佳方法是什么?

    当你跑步时Get ExecutionPolicy在 PowerShell 中 它得到有效的执行政策 https learn microsoft com en us powershell module microsoft powershell
  • 从网页运行 ClickOnce 应用程序,无需用户操作

    我们有一个基于 Java 的 Web 应用程序以及用 C 编写的相同应用程序 如果 java 检查器发现客户端计算机上没有安装 Java 则应该运行该应用程序 这个想法是运行 C 单击一次 http en wikipedia org wik
  • 索引匹配不起作用

    对于下表 如果 A 列和 B 列都匹配 如何检索 C 列A 列 B 列 C 列城市 1 城市 10 本地城市 2 城市 21 远程城市 3 城市 1 远程城市 4 城市 2 本地 我尝试使用索引和匹配 但得到 N A Enter as an
  • 模板外部链接?谁能解释一下吗?

    模板名称具有链接 3 5 非成员函数模板可以有内部链接 任何其他模板名称应具有外部链接 从具有内部链接的模板生成的实体与在其他翻译单元中生成的所有实体不同 我知道使用关键字的外部链接 extern C EX extern C templat
  • 如何在 C# 中创建异步方法?

    我读过的每一篇博客文章都会告诉您如何在 C 中使用异步方法 但由于某些奇怪的原因 从未解释如何构建您自己的异步方法来使用 所以我现在有这段代码使用我的方法 private async void button1 Click object se
  • Oauth2中如何同时撤销RefreshToken和使AccessToken失效

    我正在使用 Owin Oauth2 授权和资源服务器相同 开发单页面应用程序 AngularJS Net MVC Json Rest API 的身份验证流程 我选择了 Bearer Token 路由而不是传统的 cookie session
  • 比较:接口方法、虚方法、抽象方法

    它们各自的优点和缺点是什么 接口方法 虚拟方法 抽象方法 什么时候应该选择什么 做出这一决定时应牢记哪些要点 虚拟和抽象几乎是一样的 虚方法在基类中有一个实现 可以选择重写 而抽象方法则没有 并且must在子类中被覆盖 否则它们是相同的 在
  • 使动态创建的链接标签在 Winforms 中可点击

    我正在制作一个程序 允许用户单击由动态链接标签创建的公司名称 在我想知道如何做到这一点之前 我从未在 C 中使用过链接标签 可为特定用户生成的业务数量各不相同 因此每个用户的链接标签数量并不相同 然后我想捕获业务 ID 以进行 Json 调
  • C++:为什么 numeric_limits 对它不知道的类型起作用?

    我创建了自己的类型 没有任何比较器 也没有专门化std numeric limits 尽管如此 由于某种原因 std numeric limits
  • 如何在 sql azure 上运行 aspnet_regsql? [复制]

    这个问题在这里已经有答案了 可能的重复 将 ASP NET 成员资格数据库迁移到 SQL Azure https stackoverflow com questions 10140774 migrating asp net membersh
  • 我可以使用 lambda 函数或 std::function 对象来代替函数指针吗?

    我有一个需要使用的库 它定义了以下内容 typedef void CallbackFunction const int i 并且有一个注册回调的函数 如下所示 void registerCallback CallbackFunction p
  • 如何在 C 中将 char 连接到 char* ?

    我怎样才能前置char c to char myChar 我有c值为 A and myChar值为 LL 我怎样才能前置c to myChar使 ALL 这应该有效 include

随机推荐

  • Python:为什么运算符“is”和“==”有时对于字符串可以互换? [复制]

    这个问题在这里已经有答案了 可能的重复 Python 中的字符串比较 is 与 https stackoverflow com q 2988017 1577343 Python 字符串实习 https stackoverflow com q
  • 如何摆脱投影仪中的导航栏[重复]

    这个问题在这里已经有答案了 如何删除从投影仪乳胶文件生成的每张幻灯片顶部的部分和小节的导航栏 顺便说一句 我在序言中写道 setbeamertemplate navigation symbols usepackage beamertheme
  • 如何在 R 中捕获错误/异常? [复制]

    这个问题在这里已经有答案了 可能的重复 R 中的异常处理 https stackoverflow com questions 2622777 exception handling in r 有谁知道如何捕获 R 中的错 误或异常吗 就像约书
  • Go 生成的动画 GIF 在 Windows 中不起作用

    我发现一个示例在 Windows 中无法正常工作 该程序演示了 Go 标准图像包的基本用法 我们将使用它来创建位图图像序列 然后将该序列编码为 GIF 动画 package main import image image color ima
  • powershell if-else 不遵循任一分支

    我有powershell代码 target dir server share DelTmpStatus init value if Test Path target dir receivals tmp del target dir rece
  • 简单 Yarn 应用程序的 NoClassDefFoundError

    我试图从运行简单的纱线应用程序简单纱线应用程序 https github com hortonworks simple yarn app 但我在应用程序错误日志中收到以下异常 Exception in thread main java la
  • malloc 和 calloc 分配的内存块布局有何不同?

    calloc http www cplusplus com reference clibrary cstdlib calloc 分配num内存块 每个大小size void calloc size t num size t size 在内存
  • 如何在SQL Server中的历史表中存储历史记录

    我有2张桌子 Table A and Table A History Table A包含当前数据行 Table A History包含历史数据 我想要最新的数据行Table A and Table A History包含历史行 我可以想到两
  • 在 Android 中创建 CDMA (3gpp2) PDU

    我上周问了一个类似的问题 甚至在意识到问题是给出的答案是针对一个GSM PDU 3gpp https stackoverflow com a 12338541 1443717它在模拟器 android 2 2 中完美运行 我接受了答案并授予
  • 无法确定外键的复合外键排序

    Person是包含所有用户的用户模型 变更模型包括EngineerId和ManagerId 两者都是Person ID 为什么我会收到此错误 无法确定类型 ProjectName Models Change 上外键的复合外键排序 在复合外键
  • Tomcat 中的 crossContext 属性有什么作用?它是否启用会话共享?

    我能找到的一切Tomcat 5 5 文档 http tomcat apache org tomcat 5 5 doc config context html is 如果您希望在此应用程序中调用 ServletContext getConte
  • 将 Google 表单发布到 MySQL 数据库?

    我浏览了网络 谷歌等 我无法破译是否可以将谷歌表单数据发布到谷歌文档and到我网站其余部分运行的数据库 这样做的原因是 我可以允许拥有 Google 帐户的人完成大型表格或调查 我可以快速轻松地构建这些表格或调查 感谢您的任何启发性回复 是
  • 如何使 JavaFX MediaView 拉伸媒体以填充父容器?

    我试图使视频的尺寸自动拉伸并填充 MediaView 并保持视频的原始宽高比 基本上 我希望我的 MediaPlayer 在调整大小等时适合父容器 就像几乎所有视频播放器一样 如果有人能够阐明如何实现这一目标 我们将不胜感激 谢谢 下面是拉
  • 如何在不启动应用程序的情况下检查 AppleScript 是否正在运行 - 通过 osascript 实用程序

    考虑以下 AppleScript on is running appName tell application System Events to name of processes contains appName end is runni
  • 安全的跨平台协程

    我遇到的所有协程实现都使用汇编或检查的内容jmp buf 问题在于它本质上不跨平台 我认为以下实现不会导致未定义的行为或依赖于实现细节 但我从来没有遇到过这样写的协程 在线程中使用长跳转是否存在一些固有的缺陷 这段代码中是否存在一些隐藏的问
  • jQuery focus() 有时在 IE8 中不起作用

    我正在使用 jQuery 开发 web 应用程序 我有添加新行 3 个输入字段的功能 创建这些 DOM 元素后 我想要聚焦输入字段之一 我正在通过在必要的输入字段上调用 jQuery focus 函数来做到这一点 问题是调用 focus 在
  • Java中如何实现多线程

    我必须对一个以 1000 个批次运行代码的方法进行多线程处理 我需要将这些批次分配给不同的线程 目前我已经生成了 3 个线程 但所有 3 个线程都选择了第一批 1000 个线程 我希望其他批次不应该选择同一批次 而是选择其他批次 请大家帮忙
  • Android Studio 意外锁定文件协议

    我正在尝试将 android studio 项目导入到新机器中 导入进行得很好 并且项目的目录显示正确 但是 当我尝试构建或清理项目时 android studio 会引发以下错误 Gradle ngoma project refresh
  • 在 Chrome 扩展程序中读取和修改 HTTP GET 请求

    我想在 Chrome 扩展程序中读取和修改 添加 HTTP 标头 我正在使用 chrome webRequest API 来实现同样的目的 但我仍然无法阅读它 这是我的代码 chrome webRequest onBeforeSendHea
  • 为什么 QList::at() 不检查索引是否存在并返回只读值?

    这个问题更多的是一种询问 而不是实际寻求问题的解决方案 QList at 不仅不检查索引是否越界 而且还返回const因此它只能用于read only设想 const T QList at int i const 返回列表中索引位置 i 处