为什么非常量引用不能绑定到临时对象?

2024-01-08

为什么不允许获取对临时对象的非常量引用, 哪个函数getx()回报?显然,这是 C++ 标准所禁止的 但我对这种限制的目的感兴趣,不是参考达到标准。

struct X
{
    X& ref() { return *this; }
};

X getx() { return X();}

void g(X & x) {}    

int f()
{
    const X& x = getx(); // OK
    X& x = getx(); // error
    X& x = getx().ref(); // OK
    g(getx()); //error
    g(getx().ref()); //OK
    return 0;
}
  1. 很明显,对象的生命周期不可能是原因,因为 对对象的常量引用是不禁止按照 C++ 标准。
  2. 很明显,上面示例中的临时对象不是常量,因为允许调用非常量函数。例如,ref()可以修改临时对象。
  3. 此外,ref()允许你愚弄编译器并获得到这个临时对象的链接,这解决了我们的问题。

此外:

他们说“将临时对象分配给 const 引用可以延长该对象的生命周期”和“但没有提及非 const 引用”。 我的附加问题。以下赋值是否会延长临时对象的生命周期?

X& x = getx().ref(); // OK

由此有关右值引用的 Visual C++ 博客文章 https://devblogs.microsoft.com/cppblog/rvalue-references-c0x-features-in-vc10-part-2/:

... C++ 不希望你意外 修改临时的,但直接 调用非常量成员函数 可修改的右值是显式的,所以 这是允许的...

基本上,您不应该尝试修改临时对象,因为它们是临时对象,并且随时都会消失。允许您调用非常量方法的原因是,只要您知道自己在做什么并且明确地了解它(例如使用reinterpret_cast),我们就欢迎您做一些“愚蠢”的事情。但是,如果您将临时引用绑定到非常量引用,则可以“永远”继续传递它,只是为了让您对对象的操作消失,因为在此过程中您完全忘记了这是一个临时引用。

如果我是你,我会重新考虑我的功能的设计。为什么 g() 接受引用,它会修改参数吗?如果不是,请将其设为 const 引用,如果是,为什么要尝试将临时值传递给它,你不关心它是你正在修改的临时值吗?为什么 getx() 返回临时值?如果您与我们分享您的真实场景以及您想要实现的目标,您可能会得到一些关于如何实现的好建议。

违背语言并欺骗编译器很少能解决问题——通常它会产生问题。


Edit: Addressing questions in comment:
  1. X& x = getx().ref(); // OK when will x die?- 我不知道,也不关心,因为这正是我所说的“违背语言”的意思。该语言说“临时对象在语句末尾死亡,除非它们绑定到 const 引用,在这种情况下,当引用超出范围时它们就会死亡”。应用该规则,看起来 x 在下一个语句的开头就已经死了,因为它没有绑定到 const 引用(编译器不知道 ref() 返回什么)。然而,这只是一个猜测。

  2. 我清楚地说明了目的:不允许修改临时变量,因为它没有意义(忽略 C++0x 右值引用)。问题是“那为什么我可以称呼非常数成员呢?”是一个很好的答案,但我没有比上面已经说过的更好的答案。

  3. 好吧,如果我对 x 的看法是正确的X& x = getx().ref();声明最后就死了,问题就很明显了。

无论如何,根据您的问题和评论,我认为即使这些额外的答案也不会令您满意。这是最后的尝试/总结:C++ 委员会认为修改临时变量没有意义,因此,他们不允许绑定到非常量引用。我不知道,可能还涉及一些编译器实现或历史问题。然后,出现了一些具体情况,尽管困难重重,他们仍然允许通过调用非常量方法进行直接修改。但这是一个例外 - 通常不允许您修改临时变量。是的,C++ 常常就是那么奇怪。

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

为什么非常量引用不能绑定到临时对象? 的相关文章

  • Android - 存储对ApplicationContext的引用

    我有一个静态 Preferences 类 其中包含一些应用程序首选项和类似的内容 可以在那里存储对 ApplicationContext 的引用吗 我需要该引用 以便我可以在不继承 Activity 的类中获取缓存文件夹和类似内容 你使用的
  • Subversion 和 Visual Studio 项目的最佳实践

    我最近开始在 Visual Studio 中处理各种 C 项目 作为大型系统计划的一部分 该系统将用于替换我们当前的系统 该系统是由用 C 和 Perl 编写的各种程序和脚本拼凑而成的 我现在正在进行的项目已经达到了颠覆的临界点 我想知道什
  • 将字节数组转换为托管结构

    更新 这个问题的答案帮助我编写了开源项目GitHub 上的 AlicanC 现代战争 2 工具 https github com AlicanC AlicanC s Modern Warfare 2 Tool 你可以看到我是如何阅读这些数据
  • SSL/TLS/HTTPS 站点在 C#/.NET WebBrowser 控件中非常慢,但在 Internet Explorer 中则很好

    背景 我正在修改自动维基浏览器 http en wikipedia org wiki Wikipedia AutoWikiBrowser使用托管在安全服务器上的 MediaWiki 站点 我允许用户通过 C 应用程序中的 WebBrowse
  • 如何尝试/捕获所有异常

    我正在完成由其他人启动的 UWP 应用程序 该应用程序经常崩溃 我总是陷入困境应用程序 at if global System Diagnostics Debugger IsAttached global System Diagnostic
  • (const T v) 在 C 中从来都不是必需的,对吗?

    例如 void func const int i 在这里 const是不必要的 因为所有参数都是按值传递的 包括指针 真的吗 C 中的所有参数确实都是按值传递 这意味着无论您是否包含该参数 实际参数都不会改变const or not 然而
  • C# 正则表达式用于查找 中具有特定结尾的链接

    我需要一个正则表达式模式来查找字符串 带有 HTML 代码 中的链接 以获取文件结尾如 gif 或 png 的链接 示例字符串 a href site com folder picture png target blank picture
  • 将字符串中的“奇怪”字符转换为罗马字符

    我需要能够将用户输入仅转换为 a z 罗马字符 不区分大小写 所以 我感兴趣的角色只有26个 然而 用户可以输入他们想要的任何 形式 的字符 西班牙语 n 法语 e 和德语 u 都可以包含用户输入中的重音符号 这些重音符号会被程序删除 我已
  • C++中delete和delete[]的区别[重复]

    这个问题在这里已经有答案了 可能的重复 C 中的删除与删除 运算符 https stackoverflow com questions 2425728 delete vs delete operators in c 我写了一个包含两个指针的
  • mprotect 之后 malloc 导致分段错误

    在使用 mprotect 保护内存区域后第一次调用 malloc 时 我遇到分段错误 这是执行内存分配和保护的代码片段 define PAGESIZE 4096 void paalloc int size Allocates and ali
  • 带 If 的嵌套 For 循环的时间复杂度

    void f int n for int i 1 i lt n i if i int sqrt n 0 for int k 0 k lt pow i 3 k do something 我的思考过程 执行if语句的次数 sum i 1 to
  • 将带有 glut 的点击坐标添加到向量链接列表中

    我想创建一个向量链接列表 并在 GLUT 库的帮助下获取点击的位置并将它们附加到链接列表中 这些是我写的结构 typedef struct vector int x int y Vector typedef struct VectorLis
  • OpenCV 2.4.3 中的阴影去除

    我正在使用 OpenCV 2 4 3 最新版本 使用内置的视频流检测前景GMG http docs opencv org modules gpu doc video html highlight gmg gpu 3a 3aGMG GPU算法
  • 使用 Sphinx 时,如何记录没有文档字符串的成员?

    我正在为我发布的包编写文档 我发现您的文档越全面 人们就越容易找到您的包来使用 废话 实际上 我在充满爱心地编写代码的所有功能和细节方面获得了很多乐趣 然而 我对如何为类级变量编写与 Sphinx 兼容的文档感到完全困惑 特别是 我有一些e
  • 使用 WF 的多线程应用程序的错误处理模式?

    我正在写一个又长又详细的问题 但只是放弃了它 转而选择一个更简单的问题 但我在这里找不到答案 应用程序简要说明 我有一个 WPF 应用程序 它生成多个线程 每个线程执行自己的 WF 处理线程和 WF 中的错误 允许用户从 GUI 端进行交互
  • C# 中的常量和只读? [复制]

    这个问题在这里已经有答案了 可能的重复 const 和 readonly 之间有什么区别 https stackoverflow com questions 55984 what is the difference between cons
  • DataTable:通过 LINQ 或 LAMBDA 进行动态 Group By 表达式

    我有一个数据表 我想在其中对未指定数量的字段进行分组 发生这种情况的原因是用户可以选择他想要分组的字段 所以 实际上 我将选择推入列表中 在这个选择上 我必须对我的数据表进行分组 想象一下这段代码 VB 或 C 都一样 public voi
  • 使用 iTextSharp 5.3.3 和 USB 令牌签署 PDF

    我是 iTextSharp 和 StackOverFlow 的新手 我正在尝试使用外部 USB 令牌在 C 中签署 PDF 我尝试使用从互联网上挖掘的以下代码 Org BouncyCastle X509 X509CertificatePar
  • Visual Studio 2017 完全支持 C99 吗?

    Visual Studio 的最新版本改进了对 C99 的支持 最新版本VS2017现在支持所有C99吗 如果没有 C99 还缺少哪些功能 No https learn microsoft com en us cpp visual cpp
  • 服务器响应 PASV 命令返回的地址与建立 FTP 连接的地址不同

    System Net WebException 服务器响应 PASV 命令返回的地址与建立 FTP 连接的地址不同 在 System Net FtpWebRequest CheckError 在 System Net FtpWebReque

随机推荐

  • 如何改进这个排序代码? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • SQL Server 2008在生产环境中表现如何?

    我正要移动服务器 我正在和某人交谈 他们建议使用服务器上安装的 sql server express 2008 我可以完全访问服务器 这个 Express 引擎的工作速度 性能 与真正的 sql server 2008 相同吗 我知道限制
  • 如何从 sqlite 数据库填充可扩展列表视图

    我引用了一些链接 但没有得到好东西 我在 sqlite 中有一张表 有 4 列 id 菜单名称 描述 金额 我希望 menu name 应该是父级 描述和金额应该是从数据库填充的子级 当我单击特定的 menu name 时 它 应该展开并显
  • 在批处理文件参数中保留“=”(等号)字符

    我编写了一个批处理文件来启动应用程序 该应用程序不是我的 我无法修改它 批处理文件本身接受一些参数 应用程序接受其他参数 批处理文件使用 SHIFT 使用其所有选项 然后使用正确的环境启动应用程序 并将其余参数传递给应用程序 调用批处理文件
  • 将 javascript 注入 javascript 函数

    我有一个奇怪的问题 我需要将一些 javascript 注入到另一个 javascript 函数中 我正在使用一个已锁定的框架 因此我无法更改现有功能 我得到的是这样的东西 function doSomething 我可以操纵 上面 但是我
  • 在我的 Java 应用程序中添加 Web 浏览器

    我有一个java应用程序 用于查看网络内容 所以我想在我的应用程序中添加一个功能齐全的浏览器 我已经尝试过了JEditorPane并且它不处理动态内容 还有其他办法吗 有关如何做的任何帮助吗 这个链接是很好的例子 在 swing 中创建浏览
  • 如何在Java/Swing中使用JLabel制作动画?

    我有一个Java课程的期末项目 它是青蛙跳跃游戏 这是描述它的视频 https www youtube com watch v NxWWP9cK24o https www youtube com watch v NxWWP9cK24o 我不
  • # 登录 CSS 选择器

    一些 CSS 选择器有 在他们面前 这意味着什么 它是 ID 选择器 CSS 标准的基本功能 它根据给定的 ID 匹配 HTML 元素id属性 当然 假设有一个合格的文档 看W3C 选择器规范 http www w3 org TR sele
  • iframe 可以在 WKWebView 中与 Cordova 一起使用吗?

    根据 Apache Cordova 博客 iframe 可能无法使用 WKWebView https cordova apache org news 2018 08 01 future cordova ios webview html ht
  • 将 javascript 代码段附加到 body 标记的末尾

    我正在寻找一种将 javascript 代码块插入到 ASP NET 页面末尾的方法 Page ClientScript RegisterClientScriptBlock typeof Page showVideo sScript tru
  • 使用 HQL 选择集合

    我有以下课程 人 java class Person String name Set
  • 与变量的抽象矩阵乘法

    我知道 python 进行矩阵乘法的能力 不幸的是我不知道如何抽象地做到这一点 所以不与 确定的数字 但带有变量 Example M 1 0 1 d a c 0 1 有没有办法定义a c和d 以便矩阵乘法 给我 1 d a a d c Us
  • 折叠过渡不适用于 Angular 的 UI Bootstrap

    我正在尝试创建一个 div 当单击按钮时它将显示 隐藏 这UI 引导页面 https angular ui github io bootstrap 显示了一个使用 css 过渡的简单示例 这是我的fiddle https jsfiddle
  • 如何反编译在 VS.net 中创建的 .dll 文件

    我需要反编译在 VS net 中创建的 dll 文件 有没有可用的工具来执行此操作 或者我可以有一些代码来做到这一点吗 请帮忙 编辑2 我现在使用来自 Jetbrains 的 DotPeek https www jetbrains com
  • [-f:未找到命令,Bash 脚本文件确实存在[重复]

    这个问题在这里已经有答案了 我正在尝试编写的脚本遇到问题 缩小并简化了代码 它给出了未找到命令的错误 如果我在命令行中执行 test f file 它不会返回任何内容 而不是找不到命令 PATH 1 bin bash DIR 1 if f
  • 在 Tomcat 7 中使用智能卡和 LDAP 对用户进行身份验证

    我有一个在 Tomcat 7 上运行的 Web 应用程序 它配置了自定义 JNDIRealm 并且 web xml 中的登录配置身份验证方法设置为 FORM 我正在尝试找到一种方法来添加通过同一 LDAP 使用智能卡 如果有 对用户进行身份
  • $.getScript 中未定义函数

    这个一定很简单 外部 javascript 文件包含 function Hello alert Hello It is getScript ed 然后调用一个包含的函数 I get ReferenceError Hello 未定义 但是如果
  • 返回 404 错误的 Apache 自定义 404 页面

    我的 apache 404 php 上有一个自定义 404 错误页面 它可以正常工作 但是如果有人或任何搜索引擎请求 404 php页面 服务器返回200 OK 因为该页面确实存在 我已经把Disallow 404 php on my ro
  • 为什么要在自定义计算表达式生成器中使用 Builder.Source()?

    阅读通过F 4 0 规范 http fsharp org specs language spec 我在PDF第79页看到以下内容 辅助功能src e 表示b Source e 如果最里面的 ForEach 来自用户代码而不是由翻译生成 并且
  • 为什么非常量引用不能绑定到临时对象?

    为什么不允许获取对临时对象的非常量引用 哪个函数getx 回报 显然 这是 C 标准所禁止的 但我对这种限制的目的感兴趣 不是参考达到标准 struct X X ref return this X getx return X void g