解决 C++ 对临时变量的非常量引用的限制

2024-01-06

我有一个 C++ 数据结构,它是其他计算所需的“暂存器”。它的寿命不长,并且不经常使用,因此对性能不是至关重要的。然而,它在其他可更新的跟踪字段中包括一个随机数生成器,虽然生成器的实际值并不重要,但它is重要的是该值被更新而不是复制和重用。这意味着一般来说,此类的对象是通过引用传递的。

如果一个实例只需要一次,最自然的方法是在需要的地方构造它们(可能使用工厂方法或构造函数),然后将暂存器传递给使用方法。消费者的方法签名使用按引用传递,因为他们不知道这是唯一的用途,但工厂方法和构造函数按值返回 - 并且您不能按引用传递未命名的临时对象。

有没有办法避免使用讨厌的临时变量堵塞代码?我想避免以下情况:

scratchpad_t<typeX<typeY,potentially::messy>, typename T> useless_temp = factory(rng_parm);
xyz.initialize_computation(useless_temp);

我本质上可以制作便签本mutable并标记所有参数const &,但这并不让我觉得是最佳实践,因为它具有误导性,而且我不能对我不能完全控制的类执行此操作。通过右值引用传递将需要向暂存器的所有使用者添加重载,这违背了目的 - 拥有清晰简洁的代码。

鉴于性能并不重要(但代码大小和可读性很重要),传递这样的暂存器的最佳实践方法是什么?使用 C++0x 功能是可以的,如果required但最好仅 C++03 的功能就足够了。

Edit:需要明确的是,使用临时变量是可行的,这只是我想避免的代码中的不幸混乱。如果您从不给临时名称命名,那么它显然只使用一次,并且需要阅读的代码行越少越好。此外,在构造函数的初始值设定项中,不可能声明临时变量。


虽然不能将右值传递给接受非常量引用的函数,但可以对右值调用成员函数,但成员函数不知道它是如何调用的。如果返回对当前对象的引用,则可以将右值转换为左值:

class scratchpad_t
{
    // ...

public:

    scratchpad_t& self()
    {
        return *this;
    }
};

void foo(scratchpad_t& r)
{
}

int main()
{
    foo(scratchpad_t().self());
}

请注意如何调用self()即使产生左值表达式scratchpad_t是一个右值。

如果我错了,请纠正我,但右值引用参数不接受左值引用,因此使用它们需要向暂存器的所有使用者添加重载,这也是不幸的。

嗯,你可以使用模板...

template <typename Scratch> void foo(Scratch&& scratchpad)
{
    // ...
}

如果你打电话foo带有右值参数,Scratch将被推导为scratchpad_t, 因此Scratch&&scratchpad_t&&.

如果你打电话foo带有左值参数,Scratch将被推导为scratchpad_t&,并且由于参考折叠规则,Scratch&&也将是scratchpad_t&.

注意形式参数scratchpad是一个名称,因此也是一个左值,无论其类型是左值引用还是右值引用。如果你想通过scratchpad对于其他函数,您不再需要这些函数的模板技巧,只需使用左值引用参数即可。

顺便说一句,您确实意识到临时暂存器涉及xyz.initialize_computation(scratchpad_t(1, 2, 3));将尽快被摧毁initialize_computation完成了,对吗?将引用存储在xyz对于后来的用户来说,对象将是一个非常糟糕的主意。

self()不需要是成员方法,它可以是模板函数

是的,这也是可能的,尽管我会重命名它以使意图更清晰:

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

解决 C++ 对临时变量的非常量引用的限制 的相关文章

  • 我如何才能等待多个事情

    我正在使用 C 11 和 stl 线程编写一个线程安全队列 WaitAndPop 方法当前如下所示 我希望能够将一些内容传递给 WaitAndPop 来指示调用线程是否已被要求停止 如果 WaitAndPop 等待并返回队列的元素 则应返回
  • 通过 CMIS (dotCMIS) 连接到 SP2010:异常未经授权

    我正在使用 dotCMIS 并且想要简单连接到我的 SP2010 服务器 我尝试用 C 来做到这一点 如下所示http chemistry apache org dotnet getting started with dotcmis htm
  • 查找c中结构元素的偏移量

    struct a struct b int i float j x struct c int k float l y z 谁能解释一下如何找到偏移量int k这样我们就可以找到地址int i Use offsetof 找到从开始处的偏移量z
  • Asp.NET WebApi 中类似文件名称的路由

    是否可以在 ASP NET Web API 路由配置中添加一条路由 以允许处理看起来有点像文件名的 URL 我尝试添加以下条目WebApiConfig Register 但这不起作用 使用 URIapi foo 0de7ebfa 3a55
  • 类模板参数推导 - clang 和 gcc 不同

    下面的代码使用 gcc 编译 但不使用 clang 编译 https godbolt org z ttqGuL template
  • 用于登录 .NET 的堆栈跟踪

    我编写了一个 logger exceptionfactory 模块 它使用 System Diagnostics StackTrace 从调用方法及其声明类型中获取属性 但我注意到 如果我在 Visual Studio 之外以发布模式运行代
  • HTTPWebResponse 响应字符串被截断

    应用程序正在与 REST 服务通信 Fiddler 显示作为 Apps 响应传入的完整良好 XML 响应 该应用程序位于法属波利尼西亚 在新西兰也有一个相同的副本 因此主要嫌疑人似乎在编码 但我们已经检查过 但空手而归 查看流读取器的输出字
  • Clang 3.1 + libc++ 编译错误

    我已经构建并安装了 在前缀下 alt LLVM Clang trunk 2012 年 4 月 23 日 在 Ubuntu 12 04 上成功使用 GCC 4 6 然后使用此 Clang 构建的 libc 当我想使用它时我必须同时提供 lc
  • 不同枚举类型的范围和可转换性

    在什么条件下可以从一种枚举类型转换为另一种枚举类型 让我们考虑以下代码 include
  • 堆栈溢出:堆栈空间中重复的临时分配?

    struct MemBlock char mem 1024 MemBlock operator const MemBlock b const return MemBlock global void foo int step 0 if ste
  • 使用 WebClient 时出现 System.Net.WebException:无法创建 SSL/TLS 安全通道

    当我执行以下代码时 System Net ServicePointManager ServerCertificateValidationCallback sender certificate chain errors gt return t
  • 带动态元素的 WPF 启动屏幕。如何?

    我是 WPF 新手 我需要一些帮助 我有一个加载缓慢的 WPF 应用程序 因此我显示启动屏幕作为权宜之计 但是 我希望能够在每次运行时更改屏幕 并在文本区域中显示不同的引言 这是一个生产力应用程序 所以我将使用非愚蠢但激励性的引言 当然 如
  • 如何序列化/反序列化自定义数据集

    我有一个 winforms 应用程序 它使用强类型的自定义数据集来保存数据进行处理 它由数据库中的数据填充 我有一个用户控件 它接受任何自定义数据集并在数据网格中显示内容 这用于测试和调试 为了使控件可重用 我将自定义数据集视为普通的 Sy
  • 链接器错误:已定义

    我尝试在 Microsoft Visual Studio 2012 中编译我的 Visual C 项目 使用 MFC 但出现以下错误 error LNK2005 void cdecl operator new unsigned int 2
  • 基于 OpenCV 边缘的物体检测 C++

    我有一个应用程序 我必须检测场景中某些项目的存在 这些项目可以旋转并稍微缩放 更大或更小 我尝试过使用关键点检测器 但它们不够快且不够准确 因此 我决定首先使用 Canny 或更快的边缘检测算法 检测模板和搜索区域中的边缘 然后匹配边缘以查
  • 如何将服务器服务连接到 Dynamics Online

    我正在修改内部管理应用程序以连接到我们的在线托管 Dynamics 2016 实例 根据一些在线教程 我一直在使用OrganizationServiceProxy out of Microsoft Xrm Sdk Client来自 SDK
  • Windows 和 Linux 上的线程

    我在互联网上看到过在 Windows 上使用 C 制作多线程应用程序的教程 以及在 Linux 上执行相同操作的其他教程 但不能同时用于两者 是否存在即使在 Linux 或 Windows 上编译也能工作的函数 您需要使用一个包含两者的实现
  • 使用.NET技术录制屏幕视频[关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 有没有一种方法可以使用 NET 技术来录制屏幕 无论是桌面还是窗口 我的目标是免费的 我喜欢小型 低
  • 对来自流读取器的过滤数据执行小计

    编辑问题未得到解答 我有一个基于 1 个标准的过滤输出 前 3 个数字是 110 210 或 310 给出 3 个不同的组 从流阅读器控制台 问题已编辑 因为第一个答案是我给出的具体示例的字面解决方案 我使用的实际字符串长度为 450 个
  • 用于验证目的的动态查找方法

    我正在使用 Ruby on Rails 3 0 7 我想在运行时查找一些记录以进行验证 但为该查找方法传递 设置一个值 也就是说 在我的班级中 我有以下内容 class Group lt lt ActiveRecord Base valid

随机推荐

  • 并行性如何使用matlab求解ODE参数扫描

    只是想问一些有关我的代码的问题 从互联网上获取了此代码 这可能与 mathworks 网站中的示例相同 我在 MATLAB 中模拟此代码并得到了结果 我可以看到解决该问题所需的时间更少使用并行计算 具有 2 个工作线程的 matlabpoo
  • 在模板中同时迭代两个字典

    我试图在模板中同时打印两个字典的值 例如 td key td td value from dict1 td td value from dict2 td 两个字典包含相同的键但不同的值 有什么办法可以实现这一点吗 您可以使用自定义过滤器来完
  • 谷歌地图图像?

    有什么办法可以捕捉谷歌地图的图像吗 我无法使用静态地图 因为我在地图中有自己的折线 并且我希望它们出现在 屏幕截图 中 基本上 我希望用户导航地图 添加一些折线 当他单击 保存 时 我将保存线条 坐标 缩放 但我还希望有一个图像在列表中以缩
  • 删除 Service Fabric 应用程序后进程仍继续运行

    当我删除服务结构应用程序时 我已经看到了这一点 应用程序内服务的旧进程仍然继续运行 应用程序中包含的服务有以下类型 Actors 无状态服务 ASP NET 核心 当我重新部署应用程序时 我注意到了这个问题 并且 ASP NET Core
  • 如何使用 VSTS 2008 Database Edition GDR 版本编辑数据库对象的默认模板

    我正在尝试使用 Visual Studio Team System 2008 数据库版 GDR 版本 来完成我正在开发的一个新项目 并且遇到了一个有点烦人的问题 我希望有人知道如何解决该问题 简而言之 我想更改用于生成数据库对象 特别是存储
  • 使用 FireDac (Delphi) 在 Firebird 中创建数据库

    我最近从 AnyDac 更改为 FireDac 8 0 5 3365 我们正在运行 Delphi 2006 当我使用该组件的 AnyDac 版本时 我可以通过执行以下操作来创建一个新数据库 设置我的连接 fConnection LoginP
  • 在 C# 应用程序中管理多个 Windows 窗体

    关于管理具有多种形式的应用程序的好方法的任何想法 建议 模式 第一个页面是登录 加载 主表单 用户可以从那里启动许多其他 子表单 可能会随着时间的推移而增长 用户应该能够随时取消整个应用程序 我知道我现在做事的方式并不总是优雅的 Cody
  • 使用 git/github 对 R 包进行版本控制?

    我在确定更新 github 上 R 包版本号的工作流程时遇到问题 以避免错误命名 中间 版本 这就是我现在所做的 提交并推送 例如版本 1 0 0 并将发行版设置为 1 0 0 提交并推送一些错误修复等 而不更改描述文件 最终决定我应该将版
  • git pull 实际上并没有从远程恢复我丢失的文件

    我一直在一个分支机构工作 我提交并将其推送到远程存储库 现在该分支上的一些文件丢失了 希望它们在远程分支上仍然可用 所以我尝试这样做git pull git pull origin feature my branch 然而 git表示所有内
  • Objective C - 隐藏 iVar

    这是我的问题 假设我有一个名为 WebServiceBase h 的类 我需要在该类中添加一个名为 NSString requestData 的 iVar 但我不需要将该 iVar 添加到头文件中并使其对外部人员可见 如果我将其作为类库分发
  • SQL在分割字符串后将数据插入到其他表中

    我有一张桌子WCA ID TYPE 1 1 3 5 2 1 5 现在我想将数据移动到新表WCA TYPE ID WCA ID TYPE 1 1 1 2 1 3 3 1 5 4 2 1 5 2 5 这里的ID是自动增加的 如何在 MS SQL
  • 数据更改时 LiveData 不更新

    我正在使用 LiveData 从服务器获取数据并观察它 我的onChanged 方法只在第一次被调用 当服务器中的数据更新时不会被调用 用户片段 UserViewModel userViewModel ViewModelProviders
  • 如何向 QMainWindow 添加背景图像?

    大家好 我是 QT 创建者的新手 我尝试了很多方法来设置 Q 主窗口的背景图像 我添加了一个带有图像的资源文件夹 我尝试在 UI 中使用 setstylesheet 添加并尝试对其进行编码 当我使用用户界面时 我可以看到图像 但当我运行它时
  • 具有多个命名空间的 VBA SelectSingleNode xpath

    我遇到了与其他人类似的问题 尝试通过具有两个命名空间的 XML 使用 xPath 进行搜索 但仍在查看其他主题 但它似乎不起作用 XML
  • 更新一类中的多个项目,而不仅仅是一个

    在此代码的更新部分中 只有第一个制作的蝙蝠受到 Bat 类中 update 的影响 主循环之外 START BAT COUNT 30 BAT IMAGE PATH os path join Sprites Bat enemy Bat 1 p
  • Kubernetes - 如果容器无法重新触发初始化容器,则强制 pod 重新启动

    我在我的 pod 中发现 如果容器因存活探针失败而失败或被终止 容器会重新启动 但 pod 不会 这意味着initContainers在容器崩溃的情况下不会再次运行 就我而言 我确实需要运行其中之一initContainers每次主容器失败
  • 我应该用什么来替换 hibernate 已弃用的 @TypeDef 和 @Type 注释?

    我刚刚将 Hibernate 使用的版本升级到 5 6 1 现在似乎弃用了一些与类型相关的注释 TypeDef name json typeClass JsonBinaryType class Type type json 我没有找到任何关
  • 使用 Inno Setup 安装隐藏文件

    我需要使用 Inno Setup 创建的安装程序在最终用户计算机上安装一组跨越多个文件夹的隐藏文件 我已经提到过在 Inno Setup 中复制隐藏文件 https stackoverflow com questions 34050206
  • 游戏中心与 Sprite Kit 集成?

    如何将 Game Center 或 GameKit Framework 与 Sprite Kit Xcode 模板结合使用 在Sprite套件中 它使用Scenes 但通常要查看排行榜 例如您需要 presentModalViewContr
  • 解决 C++ 对临时变量的非常量引用的限制

    我有一个 C 数据结构 它是其他计算所需的 暂存器 它的寿命不长 并且不经常使用 因此对性能不是至关重要的 然而 它在其他可更新的跟踪字段中包括一个随机数生成器 虽然生成器的实际值并不重要 但它is重要的是该值被更新而不是复制和重用 这意味