重载按值传递和按右值引用传递

2024-01-09

我有两个子例程重载,该子例程采用占用几兆动态内存的类型参数,并具有移动构造函数和赋值运算符:

// Version intended for use when we the caller has 
// deliberately passed an rvalue reference using std::move
void MyClass::setParameter(MyMoveableType &&newParameter)
{
    m_theLocalParameter = std::move(newParameter);
}

// Version intended for use when the caller has passed
// some other type of value which shouldn't be moved
void MyClass::setParameter(MyMoveableType newParameter) 
{
    m_theLocalParameter = std::move(newParameter);
}

其意图显然是,第一个重载将 newParameter 的内容从子例程链上的任何地方移动 - 调用 newParameter 对象,而第二个重载创建 newParameter 的全新副本(或调用复制省略以避免在适当的情况下这样做,例如,参数实际上是函数的返回值),然后将副本移动到本地数据成员中,从而避免进一步的复制。

但是,如果我尝试使用第一个重载实际将对象移动到我的类中:

{
    MyClass        theDestination;
    MyMoveableType theObject
    ...
    // ...Various actions which populate theObject...
    ...

    TheDestination.setParameter(std::move(theObject));
    ...
}

...然后在我尝试过的每个编译器上都会出现以下错误:

call to member function 'setParameter' is ambiguous

现在我可以看到,如果我没有提供第一个重载,则将右值引用传递给第二个重载实际上是完全合法的,并且是我期望编译器执行的操作,而不发出警告。即便如此,我希望编译器能够完全清楚这段代码的意图是什么,因此我希望它会选择第二个重载作为最佳匹配。

我可以通过重新定义第二个构造函数以采用 const 引用并消除 std::move 来消除错误(尽管这不会是一个错误 把它留在里面;编译器会忽略它)。这可以正常工作,但我会失去利用复制省略的机会。这可能是 对于该特定应用而言,性能方面具有重要意义;所讨论的对象是以 30 传输的高分辨率视频帧 每秒帧数。

在这种情况下,我可以做些什么来消除重载的歧义,从而使我的例程同时具有按值传递和按右值引用传递版本吗?


其意图显然是,第一个重载将 newParameter 的内容从子例程链上的任意位置移动 - 调用 newParameter 对象,而第二个重载则创建一个全新的副本

这并不是你真正的做法。你有两个明智的选择:

方法A

你写只是价值超载然后无论如何都要从它移走 - 这意味着你总是要付出构造函数的代价,无论是移动还是复制。

方法B

您为以下内容编写重载(const T&) and (T&&)。这样,您可以复制第一个,并使用完美转发跳过第二个中的移动 CTOR。


我建议将方法 A 作为默认值,仅当 c-tor 调用实际上很重要时才使用方法 B。

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

重载按值传递和按右值引用传递 的相关文章

随机推荐

  • Java RMI - 套接字权限问题

    我在尝试将 java 程序连接到 2 个不同的套接字时遇到问题 基本上我想初始化我的 RMI 服务器 连接到端口 1099 然后在端口 10002 上初始化 PrologBeans 初始化似乎对两者都工作得很好 但是当我尝试访问 prolo
  • 如何加速jquery mobile/phonegap?

    我有一个小型网络应用程序 七页 index html 3 6 KB 总计 855 5 KB 我唯一奇怪的是一个 Javascript 数据库 500kb 其中有很多行 例如 data db Aarstra e 34236 1 34246 2
  • Sequelizejs:错误:重复的键值违反了唯一约束“message_pkey”

    我有一个PostrgresDB 我使用sequelize与我的Nodejs应用程序连接 我试图创建并保存一个模型 但它抛出error duplicate key value violates unique constraint messag
  • 如何在 C 中创建 24 位无符号整数

    我正在开发一个 RAM 非常紧张的嵌入式应用程序 为此 我需要创建一个 24 位无符号整数数据类型 我正在使用一个结构来执行此操作 typedef struct uint32 t v 24 uint24 t 然而 当我询问这种类型的变量的大
  • ios9 Safari 错误计算总和

    我有一些代码可以循环计算哈希中的键 值之和 与其他地方相比 它在 ios9 Safari 上计算总和的方式似乎不同 虽然我可以找到一种方法来修复这个单独的用例 但我们在整个大型代码库中使用这种类型的语法 所以我正在寻找对 为什么ios9会出
  • 如何将事件接收器绑定到*特定*自定义内容类型?

    我已经创建了一个事件接收器并将其添加到 GAC 中 如何将事件接收器绑定到specific自定义内容类型 我需要从 XML 文件执行此操作 到目前为止我有 Feature xml 指向 Elements xml 文件 但不确定 Elemen
  • Android Studio 中未出现类名错误

    在下面的错误中你可以看到RegisterActivity a类名被转换为一些其他字符 当类名没有出现在错误日志中时 有人可以建议在这种情况下我应该做什么 at com abc angpau appClasses activities Reg
  • Awk 命令与 Powershell 等效

    我希望你能帮助我 本质上 我正在寻找与awk命令 awk Box11 print 0 test txt awk SUM 4 END print SUM 他的作用是打印包含字符串 Box11 的行 然后将其通过管道传输到另一个 awk 该 a
  • 将配置添加到 App.config 文件时出错

    相关问题 在另一台机器上运行我的应用程序会出现错误 https stackoverflow com questions 4225667 running my application on another machine gives me a
  • 在 HTML 中有效显示大型列表 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 Locked 这个问题及其答案是locked help locked posts因为这个问题是题外话
  • 在 ubuntu 上从 prefork MPM 切换到worker MPM + php-fpm

    我找到的所有教程都是如何全新安装worker MPM PHP FPM 因为我的wordpress博客已经使用prefork MPM启动并运行 如果我在模拟安装过程中出错 请纠正我 我在 ubuntu 上 根据一些教程 以下几行可以完成所有技
  • UITableViewCell 内容在单独重新加载单元格时闪烁

    我有一个链接到的表格视图NSFetchedResultController 即加载数据并跟踪数据更改也绑定到 FRC 我没有使用AutoLayout在我的单元格中 由于 iOS 8 中引入了巨大的性能下降 我正在单元格中手动布置单元格的内容
  • 如何打开 JQuery UI 弹出窗口 onclick

    我有简单的 html 页面
  • 为什么 Magento cart.create 函数会使购物车处于非活动状态?

    我一直在摆弄 Magento 购物车 API Magento v 1 5 发现当创建购物车 并添加产品 时 sales flat quote 表中的 is active 值设置为 0 相反 如果您使用商店界面中的 添加到购物车 按钮 则 i
  • 可以在 Redshift 上存储 JSON 字段吗?

    Redshift 是否支持 JSON 字段 例如 Postgresql 的 json 数据类型 如果是的话我该怎么做才能使用它 您可以将 JSON 存储在 Amazon Redshift 中的普通文本字段内 有一些函数可用于从 JSON 字
  • 为什么当 Android 中的区域更改时 DateTimeZone.getDefault() 没有更新

    我在 Stackoverflow 上查看了许多与时区相关的问题 但我找不到我所遇到的问题的问题 为什么乔达没有DateTimeZone getDefault 返回 TZ 更改时更新的时区 恢复应用程序后 TimeZone getDefaul
  • MKMapPointForCoordinate 返回无效坐标

    我正在使用 MKMapView 注释 叠加等 但我在 MKMapPointForCooperative 返回无效坐标的问题上遇到了麻烦 Code MKMapPoint pointArr for Category route in valid
  • 在java 8中,为什么无法调用当前类正在实现的接口静态方法[重复]

    这个问题在这里已经有答案了 我最近正在研究 Java 8 的新功能 并观察到一个有趣的行为 这没关系 Class A static void staticMethodInA println Class B extends A B stati
  • 获取Oracle中两个日期之间的天数,包括日期

    我想获取两个提供的日期之间的总天数 我尝试过以下查询 但没有得到完全不同的结果 不包括最后日期 select to date 15 06 13 dd MM yyyy to date 01 02 12 dd MM yyyy from dual
  • 重载按值传递和按右值引用传递

    我有两个子例程重载 该子例程采用占用几兆动态内存的类型参数 并具有移动构造函数和赋值运算符 Version intended for use when we the caller has deliberately passed an rva