我通常/总是可以使用 std::forward 而不是 std::move 吗?

2023-12-12

我一直在看斯科特·迈耶斯的谈论通用参考来自 C++ and Beyond 2012 会议,到目前为止一切都有意义。然而,在50分钟左右,一位观众问了一个我也想知道的问题。迈耶斯说他并不关心答案,因为这不符合惯用语,而且会让他的头脑变得愚蠢,但我仍然感兴趣。

给出的代码如下:

// Typical function bodies with overloading:
void doWork(const Widget& param)   // copy
{
  // ops and exprs using param
}
void doWork(Widget&& param)        // move
{
  // ops and exprs using std::move(param)
}

// Typical function implementations with universal reference:
template <typename T>
void doWork(T&& param)             // forward => copy and move
{
  // ops and exprs using std::forward<T>(param)
}

要点是,当我们获取右值引用时,我们知道我们有一个右值,所以我们应该std::move它是为了保留它是右值的事实。当我们采用通用参考(T&&, where T是推导类型),我们想要std::forward保留它可能是左值或右值的事实。

所以问题是:自从std::forward保留传递给函数的值是左值还是右值,并且std::move只是将其参数转换为右值,我们可以使用std::forward到处?会std::forward表现得像std::move在我们使用的所有情况下std::move,或者是否存在一些被迈耶斯的概括所遗漏的重要行为差异?

我并不是建议任何人都应该这样做,因为正如迈耶斯正确所说,它完全不惯用,但以下也是有效的用法std::move:

void doWork(Widget&& param)         // move
{
  // ops and exprs using std::forward<Widget>(param)
}

两者非常不同并且补充 tools.

  • std::move deduces参数并无条件创建一个右值表达式。这对于应用于实际对象或变量是有意义的。

  • std::forward接受一个强制模板参数(你必须指定这个!)并根据类型神奇地创建一个左值或右值表达式(通过添加&&以及崩溃的规则)。这仅适用于推导的模板化函数参数才有意义。

也许下面的例子能更好地说明这一点:

#include <utility>
#include <memory>
#include <vector>
#include "foo.hpp"

std::vector<std::unique_ptr<Foo>> v;

template <typename T, typename ...Args>
std::unique_ptr<T> make_unique(Args &&... args)
{
    return std::unique_ptr<T>(new T(std::forward<Args>(args)...));  // #1
}

int main()
{
    {
        std::unique_ptr<Foo> p(new Foo('a', true, Bar(1,2,3)));
        v.push_back(std::move(p));                                  // #2
    }

    {
        v.push_back(make_unique<Foo>('b', false, Bar(5,6,7)));      // #3
    }

    {
        Bar b(4,5,6);
        char c = 'x';
        v.push_back(make_unique<Foo>(c, b.ready(), b));             // #4
    }
}

在情况 #2 中,我们有一个现有的具体对象p,我们想无条件地摆脱它。仅有的std::move说得通。这里没有什么可以“转发”的。我们有一个命名变量,我们想从它移走。

另一方面,情况 #1 接受任何类型参数的列表,并且每个参数都需要作为与原始调用中相同的值类别转发。例如,在 #3 中,参数是临时表达式,因此它们将作为右值转发。但是我们也可以在构造函数调用中混合命名对象,如情况 #4 所示,然后我们需要作为左值转发。

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

我通常/总是可以使用 std::forward 而不是 std::move 吗? 的相关文章

  • json.net自定义jobject反序列化

    我正在尝试使用 JsonConvert DeserializeObject string 将字符串反序列化为可与动态一起使用的 jobject 来动态访问 json 文档 但是我想避免知道文档的大小写 以便我可以输入 dynamic doc
  • Poco c++Net:Http 从响应中获取标头

    我使用 POCO C Net 库进行 http 我想尝试制定持久缓存策略 首先 我认为我需要从缓存标头中获取过期时间 并与缓存值进行交叉检查 如果我错了 请告诉我 那么我如何从中提取缓存头httpResponse 我已经看到你可以用 Jav
  • 如何在另一个应用程序中挂钩 api 调用

    我正在尝试挂钩另一个应用程序的 ExtTextOut 和 DrawTextExt GDI 方法调用 我知道我需要使用 GetProcAddress 来查找 gdi32 dll 中那些方法的地址 并用我的函数的地址覆盖我想要挂钩的进程中的地址
  • 检测wlan是否关闭

    任何人都可以给我一个提示 如何在 Windows Phone 上以编程方式检测 C 8 1 应用程序 不是 8 0 是否启用 禁用 WLAN 我不想更改这些设置 只是需要知道 该解决方案是一个 Windows 8 1 通用应用程序 Wind
  • 从代码中,如何创建对存储在附加属性中的对象的属性的绑定?

    我们有一个继承的附加属性来存储一个对象 在可视化树的更下方 我们希望从代码绑定到该对象的属性 通常我们像这样构建绑定的路径部分 var someBinding new Binding Path new PropertyPath Attach
  • 运行需要 MySql.Data 的内置 .NET 应用程序

    我在运行我编写的内置 NET 应用程序时遇到问题 我的应用程序使用最新的 MySql 连接器 该连接器安装在我的系统上 当我尝试将其添加为引用时 该连接器显示为 NET 4 Framwork 组件 当我在环境中以调试模式运行应用程序时 一切
  • Gwan C#,如何获取HTTP标头?

    我需要它来重写 url 以了解我正在处理哪个友好的 url 用于用户代理和其他东西 EDIT public class Gwan MethodImplAttribute MethodImplOptions InternalCall exte
  • 在 omp 并行 for 循环中使用 unique_ptr 会导致 SEG.FAULT

    采取以下代码 include
  • 使用 LINQ 更新 IEnumerable 对象的简单方法

    假设我有一个这样的业务对象 class Employee public string name public int id public string desgination public int grade List
  • 获取 boost Spirit 语法中的当前行

    我正在尝试使用 boostspirit 获取正在解析的文件的当前行 我创建了一个语法类和结构来解析我的命令 我还想跟踪在哪一行找到命令并将其解析到我的结构中 我将 istream 文件迭代器包装在 multi pass 迭代器中 然后将其包
  • 增强精神、递归和堆栈溢出

    为什么下面的代码在运行时崩溃 它会给出堆栈溢出错误 include
  • C# 编译器不会优化不必要的强制转换

    前几天 在写答案的时候这个问题 https stackoverflow com questions 2208315 why is any slower than contains在这里 关于溢出 我对 C 编译器感到有点惊讶 它没有按照我的
  • MFC:如何设置CEdit框的焦点?

    我正在开发我的第一个简单的 MFC 项目 但我正在努力解决一个问题 想要设置所有的焦点CEdit其中一个对话框中的框 我的想法是 当打开对话框时 焦点位于第一个编辑框上 然后使用 选项卡 在它们之间交换 我看到了方法SetFocus 但我无
  • 使用 C# 和 wpf 创建类似 Dock 的应用程序

    我需要创建一个与我们购买笔记本电脑时获得的应用程序类似的应用程序 仅当鼠标指针到达窗口顶部时它才可见 那么我怎样才能使用 C 4 0 来做到这一点呢 http www notebookcheck net uploads pics win2
  • 在 asp.net MVC 中使用活动目录进行身份验证

    我想使用活动目录对我的 asp net mvc 项目中的用户进行身份验证 在网上冲浪了几个小时后 我没有找到任何对我有用的东西 我已经看到了所有结果 但什么也没有 我尝试按照许多帖子的建议编辑我的 web config 如果有人可以帮助我提
  • 如何从 Rx Subscribe 回调异步函数?

    我想回调 Rx 订阅中的异步函数 例如 像那样 public class Consumer private readonly Service service new Service public ReplaySubject
  • Linux mremap 不释放旧映射?

    我需要一种方法将页面从一个虚拟地址范围复制到另一个虚拟地址范围 而无需实际复制数据 范围很大 延迟很重要 mremap 可以做到这一点 但问题是它也会删除旧的映射 由于我需要在多线程环境中执行此操作 因此我需要旧映射能够同时使用 因此稍后当
  • ASP.NET MVC 路由:如何从 URL 中省略“索引”

    我有一个名为 StuffController 的控制器 具有无参数索引操作 我希望从表单中的 URL 调用此操作mysite com stuff 我的控制器定义为 public class StuffController BaseContr
  • .NET 4 的条件编译[重复]

    这个问题在这里已经有答案了 可能的重复 条件编译和框架目标 https stackoverflow com questions 2923210 c sharp conditional compilation and framework ta
  • 使用 using 声明时,非限定名称查找如何工作?

    根据 C 标准 这是格式错误还是格式良好 namespace M struct i namespace N static int i 1 using M i using N i int main sizeof i Clang 拒绝它 GCC

随机推荐

  • 为什么当 CollapsingToolbarLayout 完全折叠时 NestedScrollView 停止滚动?

    我在用collapsingToolbarlayout with nestedscrollview它工作正常 直到collapsingToolbarlayout完全崩溃了并且actionbar正在显示 这里的nestedscrollview停
  • Angular 5 每次点击路线时滚动到顶部

    我正在使用 Angular 5 我有一个仪表板 其中有几个部分内容较小 而少数部分内容较大 以至于我在转到顶部时更改路由器时遇到问题 每次我都需要滚动到顶部 如何解决这个问题 以便当我更换路由器时 我的视图始终保持在顶部 有一些解决方案 请
  • 基于 Sublime Text 3 的 Python 2.7 版本不打印 '\uFFFD' 字符

    问题 我正在使用基于 Sublime Text 3 构建的 Python 2 7 并且在打印时遇到问题 在某些情况下 我得到的输出非常混乱 uFFFD the REPLACEMENT CHARACTER 例如 print u ufffd s
  • 在 Twilio 队列中录制语音邮件

    我正在使用 Twilio 编写呼叫中心应用程序 但遇到了问题 电话被接收并放入队列中 同时我们找到一个代理来接听电话 当他们听等待音乐时 他们会读取自己在队列中的位置 我尝试使用 Gather 动词让他们按 1 然后留言 一切都很好 只是无
  • 是否可以在 Python 中重用导入代码?

    我的项目中的某些文件之间存在一些常见的导入 我想重用这段代码 将其集中在一个唯一的文件中 并在其他文件中只导入一次 是否可以 或者是否有另一种方法不在多个文件中复制所需的导入列表 是的 这是可能的 您可以创建一个包含导入的 Python 文
  • 当我使用这段代码时它给出错误

    public ContactEntry createContact String username throws IllegalArgumentException Create the entry to insert ContactsSer
  • Silverlight XamlWriter

    我发现 Net XamlWriter 在 Silverlight 中不可用 好吧 无论如何我都需要一个 所以我认为有一个解决方案 我有一些 UIElement 对象 路径 椭圆 矩形等 并且我想存储它们的 Xaml 定义 以便稍后可以使用
  • 在树中的节点发生更改后,将rearrangeObjects发送到NSTreeController的正确方法是什么?

    合适的获取方式是什么重新排列对象更改树中的节点后发送到 NSTreeController 我有一个示例应用程序 完整代码如下 使用 NSOutlineView 和 NSTreeController 以及简单的 Node 对象树 在应用程序的
  • 获取当前用户的全名,返回空字符串 (C#/C++)

    我尝试获取当前登录用户的全名 全名 而不是用户名 以下代码 C C 工作正常 但在未连接到网络的 XP 计算机上 如果我在登录后运行大约 20 分钟 则会得到空字符串 在登录后的前大约 20 分钟内运行正常 使用Win32 API GetU
  • 逻辑回归系数 scikit-learn 与 statsmodels

    当使用两个 API 执行逻辑回归时 它们给出不同的系数 即使使用这个简单的示例 它也不会在系数方面产生相同的结果 我遵循关于同一主题的旧建议的建议 例如在 sklearn 中为参数 C 设置一个较大的值 因为它使惩罚几乎消失 或设置pena
  • VB.Net 和 C#“作为新的 WebControl”之间的区别

    我正在重构一些代码 其中一部分包括将其从 VB Net 移至 C 旧代码声明一个成员是这样的 Protected viewMode As New WebControl 新代码 我最终开始工作 如下所示 protected WebContro
  • 防止屏幕刮擦[关闭]

    Closed 这个问题是无关 目前不接受答案 根据我的问题屏幕抓取的合法性 即使这是非法的 人们仍然会尝试 所以 可以采用哪些技术机制prevent或者至少抑制屏幕抓取 哦 只是为了笑 让生活变得困难 保留搜索引擎的访问权限可能会很好 我可
  • Leaflet - 获取弹出窗口内标记的纬度和经度

    我使用 Leaflet Draw 插件 我的目标是创建标记并显示一个弹出窗口 我可以在其中获取纬度和经度坐标 我设法通过 JavaScript 警报获取这些坐标 但我绝对不知道如何将坐标放入弹出窗口中 这是片段 map on draw cr
  • “System.Net.Mail.DeliveryNotificationOptions”仅适用于 Exchange 吗?

    我们有一个在 SharePoint 2010 服务器上运行的用于发送电子邮件的应用程序 我们 发件人 希望收到送达通知 但无法在实时系统上检索它们 我已经设置了System Net Mail DeliveryNotificationOpti
  • 调整面板大小而不重新验证

    I have aJPanel我在其中画线以创造铅笔的错觉 该面板位于ScrollPane 当我调整面板大小时 一次调用revalidate 方法会自动放置 并且我在该面板中绘制的所有线条都消失了 有什么方法可以让我在面板中绘制的线保持新的尺
  • 在 Android 运行时隐藏线性布局

    我有以下布局
  • Karma-Jasmine:如何正确监视 Modal?

    情况 我正在对我的 Angular Ionic 应用程序进行单元测试 我在使用模态时遇到了麻烦 目前我可以测试模态是否已被调用 到目前为止就是这样 我无法测试模式的正确 show 和 hide 方法 我收到以下错误 TypeError sc
  • Heroku 资产预编译

    今天 我正在使用一个在 Heroku 上运行了几个月的应用程序 为了让某些东西正常工作 我在我的开发环境中运行了它 rake assets precompile 当我提交更改并推送到 Heroku 时 我的请求出现 500 个错误 Acti
  • GoogleAnalytics HitBuilders.TimingBuilder

    我正在将 GA 用于 Android 应用程序 我试图使用用户计时来报告代码中某些操作已经过去了多少时间 所以我基本上做的是这样的 在代码中的某个时刻我得到System currentTimeMillis 在另一点上 我再次执行此操作 并从
  • 我通常/总是可以使用 std::forward 而不是 std::move 吗?

    我一直在看斯科特 迈耶斯的谈论通用参考来自 C and Beyond 2012 会议 到目前为止一切都有意义 然而 在50分钟左右 一位观众问了一个我也想知道的问题 迈耶斯说他并不关心答案 因为这不符合惯用语 而且会让他的头脑变得愚蠢 但我