STL容器函数返回值

2023-11-21

当查看 STL 容器的成员函数时,我想到了一个奇怪的想法。为什么没有像这样的功能std::vector<T>::push_back(T)没有(可选)返回值(迭代器甚至对附加对象的引用)?我知道std::string功能类似于insert and erase返回迭代器,但这是出于显而易见的原因。我认为它通常会保存这些函数调用之后的第二行代码。

我相信C++的设计者有一个很好的理由,请赐教:)

UPDATE:我在这里包含一个真实的代码示例,它可以减少代码长度:

if( m_token != "{" )
{
    m_targets.push_back( unique_ptr<Target>(new Dough(m_token)) );
    return new InnerState( *(m_targets.back()), this );
}

可以减少到

if( m_token != "{" )
    return new InnerState( *(m_targets.push_back( unique_ptr<Target>(new Dough(m_token)) )), this );

如果我假设std::list::push_back返回对添加元素的引用。代码有点重,但这主要是(两组括号)由于unique_ptr的构造函数并取消引用它。也许为了清楚起见,没有任何指针的版本:

if( m_token != "{" )
{
    m_targets.push_back( Dough(m_token) );
    return new InnerState( m_targets.back(), this );
}

vs.

if( m_token != "{" )
    return new InnerState( m_targets.push_back( Dough(m_token) ), this );

不可能以安全的方式返回添加的元素或容器成员函数中的容器。 STL容器主要提供“强有力的保障”。返回被操作的元素或容器将无法提供强保证(它只会提供“基本保证”)。 其背后的原因是,返回某些内容可能会调用复制构造函数,这可能会引发异常。但是该函数已经退出,因此它成功地完成了其主要任务,但仍然抛出异常,这违反了强保证。您可能会想:“那么让我们通过引用返回!”,虽然这听起来像是一个很好的解决方案,但它也不是完全安全的。考虑以下示例:

MyClass bar = myvector.push_back(functionReturningMyClass()); // imagine push_back returns MyClass&

尽管如此,如果复制赋值运算符抛出异常,我们不知道push_back是否成功,从而间接违反了强保证。尽管这并不是直接违规。当然使用MyClass& bar = //...相反,会解决这个问题,但这会很不方便,容器可能会进入不确定状态,只是因为有人忘记了&.

一个很相似的推理背后的事实是std::stack::pop()不返回弹出的值。反而top()以安全的方式返回最高值。调用 top 后,即使复制构造函数或复制赋值构造函数抛出异常,您仍然知道堆栈没有更改。

EDIT:我相信,如果迭代器类型的复制构造函数提供不抛出保证(我所知道的每个人都这样做),则为新添加的元素返回迭代器应该是完全安全的。

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

STL容器函数返回值 的相关文章

随机推荐

  • android logcat中的致命信号6是什么[关闭]

    Closed 这个问题需要多问focused 目前不接受答案 我是 Android 开发新手 我的应用程序在从 Activity 切换 11 次时不断被终止 而且它只说 致命信号 6 SIGABRT tid 9485 中的代码 6 Thre
  • Python/SciPy:如何从 CubicSpline 获取三次样条方程

    我正在通过给定的一组数据点生成三次样条曲线图 import matplotlib pyplot as plt import numpy as np from scipy import interpolate x np array 1 2 4
  • 如何从 Tomcat Java 应用程序捕获 SOAP 消息到外部服务器?

    我有一个 Web 应用程序 它在 Tomcat6 内运行并通过 HTTPS 将 SOAP 消息发送到某个外部系统 我想拦截这些消息 为了做到这一点 我在工具 gt Fiddler 选项对话框 重新启动 Fiddler 后 我可以看到对多个主
  • 如何读取内存中存储的图像文件?

    在我的 Android 应用程序中 我使用以下代码将图像文件存储在内部存储器中 FileOutputStream fos con openFileOutput fileName con MODE PRIVATE fos write baf
  • 在不同的控制器中设计表单

    我正在使用 devise gem 进行登录 退出程序 我从设备生成视图文件 使用rails g devise views 我看到有一个 devise sessions new html erb 文件 其中包含登录表单 我创建了另一个文件 d
  • TypeScript - 检查对象的属性是否是具有给定签名的函数

    我有一个从对象获取属性的函数 Utils ts export function getProperty
  • 如何在 Java 中将电话号码格式化为字符串?

    我一直将电话号码存储为很长的长度 我想在将电话号码打印为字符串时简单地添加连字符 我尝试使用DecimalFormat但这不喜欢连字符 可能是因为它用于格式化十进制数字而不是长整数 long phoneFmt 123456789L Deci
  • Android studio java.exe 以非零退出值 3 结束

    我已经通过了与 multidex 问题相关的非零退出值 1 2 但现在我得到了非零退出值 3 工作室留言 Information Gradle Executing tasks emoticons lib proj assembleDebug
  • 通过AJAX调用提示用户保存文件

    我正在将 DHTMLX 网格导出到 csv 并已成功创建 CSV 文件 我遇到的问题是它没有提示用户保存 打开文件 我使用 javascript 中的 post 调用将 CSV 字符串发送到 PHP 然后将该字符串写入 csv 由于某种原因
  • 如何在 C# 中使用 imageMagick

    您能解释一下如何将 ImageMagick 与 C 一起使用吗 我正在尝试将 PDF 页面转换为图像 我想运行 imageMagick 命令 convert 密度 300 input pdf output png string argume
  • 获取类函数的参数数量

    有没有办法检测类中函数的参数数量 我想做的是以下内容 class foo path path to file if file exists path die require path if class exists class die c
  • 在 Maps V2 上绘制多色折线

    我按照以下方式在地图上绘制纯色折线 效果很好 PolylineOptions polyLine new PolylineOptions polyLine width 5 polyLine color Color RED polyLine g
  • WPF 的语法荧光笔[重复]

    这个问题在这里已经有答案了 我目前正在为 WPF 应用程序寻找语法荧光笔 用户可以在文本框中输入内容 希望能够识别代码并相应地突出显示语法 我想先支持C 稍后再支持其他语言 问题重复394751 如果您不介意没有任何文档 Avalon编辑是
  • 使用@EJB时,每个托管bean是否都有自己的@EJB实例?

    我正在将 JSF 2 2 用于 Web 项目 并且现在正在实现登录页面 我有一个login xhtml作为view 和一个名为的支持 beanUserLoginView 这种豆子有一个EJB属性beanprivate UserService
  • 组合类型别名的协议和空一致协议之间的区别

    Swift 中这两者有区别吗 protocol ABProtocol AProtocol BProtocol typealias ABProtocol AProtocol BProtocol 为了让事情更清楚 我将第二个重命名为 typea
  • 从变量中批量提取路径和文件名

    如何从变量中提取路径和文件名 Setlocal EnableDelayedExpansion set file C Users l72rugschiri Desktop fs cfg 我想在不使用任何函数或任何 GOTO 的情况下做到这一点
  • ruby 的 <=> 运算符和排序方法

    player1 Player new moe player2 Player new larry 60 player3 Player new curly 125 players player1 player2 player3 上面 我创建了一
  • 路由器命名的插座被激活一次

    是否有可能让路由器命名的插座被激活一次 然后永远不会被破坏 无论主插座中导航什么路线 目的是让组件保留在页面上 例如 sidebar 但在初始加载时获得路由的好处 例如防护 解析器 和延迟加载 要求是命名的插座不应以任何负面方式影响用户体验
  • 正则表达式使用字符限制验证密码

    我需要使用以下规则验证密码 6 至 20 个字符 必须包含至少一位数字 必须包含至少一个字母 不区分大小写 可以包含以下字符 以下表达式匹配除最后一个要求之外的所有要求 最后一张我能做什么 d A z 6 20 我不完全确定我有这个权利 但
  • STL容器函数返回值

    当查看 STL 容器的成员函数时 我想到了一个奇怪的想法 为什么没有像这样的功能std vector