为什么结构化绑定禁用 RVO 并移动 return 语句?

2024-02-28

假设我们有一个名为AAA支持两者复制/移动:

class AAA
{
public:
    AAA() = default;
    ~AAA() = default;

    AAA(const AAA& rhs)
    {
       std::cout << "Copy constructor" << std::endl;
    }

    AAA(AAA&& rhs)
    {
       std::cout << "Move constructor" << std::endl;
    }
};

在下面的代码中,get_val回报second:

AAA get_val()
{
    auto [ first, second ]  = std::make_tuple(AAA{}, AAA{});

    std::cout << "Returning - " << std::endl;
    return second;
}

auto obj = get_val();
std::cout << "Returned - " << std::endl;

Now second被复制,打印以下输出:

...
Returning - 
Copy constructor 
Returned -

这是不幸的,因为我对结果的期望是要么没有调用复制构造函数,要么至少是隐含地 moved.

为了避免复制,我必须明确应用std::move on it.

return std::move(second);

然后我会收到以下结果:

...
Returning - 
Move constructor 
Returned - 

我认为原因是RVO没有执行是编译器可能会看到second作为参考,同时get_val返回纯右值。

然而,为什么隐性移动也不能被预期呢? 使用显式std::move在这种特殊情况下, return 语句看起来并不直观,因为你通常不希望 RVO 意外消失,在大多数情况下,RVO 是比 move 更好的优化 https://stackoverflow.com/questions/19267408/why-does-stdmove-prevent-rvo.

由编译器 gcc 和 clang 进行测试-O3.

现场演示 https://wandbox.org/permlink/5RPFJstLvYo62ThB


然而,为什么隐性移动也不能被预期呢?

与关闭省略的原因完全相同:因为它是参考,不是独立对象的名称。每次使用second本质上相当于说obj.whatever or get<1>(obj)(尽管在后一种情况下,我们存储引用)。这些表达式中的任何一个都没有隐含的移动。

结构化绑定用于访问给定对象的子对象。您不能忽略子对象的返回,也不能隐式地从它们中移动。因此,您不能省略结构化绑定名称,也不能隐式地从它们中移动。

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

为什么结构化绑定禁用 RVO 并移动 return 语句? 的相关文章

随机推荐

  • 按钮禁用和启用

    我有一个基于 vb net 的 Windows 应用程序 当单击 GO 按钮时 一堆数据将加载到数据库中 因此 在我的应用程序中 一旦单击 GO 按钮 我只想禁用它 并希望在上传完成后重新启用它 现在 在 btnGo Click 的特定方法
  • 如何在Java字符串中输入引号?

    我想在Java中初始化一个字符串 但是该字符串需要包含引号 例如 ROM 我尝试这样做 String value ROM 但这行不通 我怎样才能包括 s 在字符串中 在 Java 中 您可以使用转义引号 String value ROM
  • 使用 PHP 创建加密的 zip 存档

    我正在寻找一种将 txt 文件加密为 zip 的方法 但采用安全密码保护的方式 我的目标是通过电子邮件将此文件发送给我 而任何人都无法阅读附件的内容 有谁知道一种简单且最重要的是安全的方法来实现这一目标 我可以创建 zip 存档 但我不知道
  • 从命令行激活 gcloud 服务帐号时出错

    我指的是这个网址https cloud google com speech docs getting started https cloud google com speech docs getting started开始使用 google
  • Vue 不是构造函数

    I using webpack 在 chrome 中构建并运行后显示此错误 我不知道如何解决它 我的代码很简单 devDependencies babel core 6 23 1 babel loader 6 3 2 babel plugi
  • 将 XML 注释添加到 LINQ to SQL 设计器生成的类属性

    我使用 Visual Studio 中的 LINQ to SQL 设计器来创建数据库的对象模型 现在 我想向每个生成的属性添加 XML 注释 但我不知道如何在下次刷新 dbml 文件时不删除属性的情况下执行此操作 如何才能做到这一点 我相信
  • 无法从本地主机访问 Django

    这有点奇怪 我无法从本地主机访问 django 但我可以从本地 IP 访问它 python manage py runserver 0 0 0 0 8000 然后当我尝试访问时 我的主机文件 127 0 0 1 lmlicenses wip
  • -bash: ./configure: 没有这样的文件或目录 - MySQL 在 Mac OS X 10.6 上安装

    我正在尝试在 Mac OS X 10 6 上安装 MySQL 下载 MySQL 并使用 tar xzvf mysql 5 1 37 tar gz 解压后 我尝试运行此配置行 configure prefix usr local mysql
  • 使用 popen() 调用 shell 命令?

    当通过 xcode 运行以下代码时 我得到不一致的行为 有时它会正确打印 git 版本 有时它不会打印任何内容 但 shell 命令的返回码始终为 0 关于为什么会这样的任何想法吗 我究竟做错了什么 define BUFFER SIZE 2
  • UIRefreshController 结束动画问题

    当我呼唤self refreshControl endRefreshing 它将 tableView 像它应该的那样恢复到原来的位置 我应该如何对其进行动画处理 以便它能够流畅地返回到原来的位置endRefreshing Try this
  • UINavigationBar - 更改 UIBarButtonItem 位置

    我在我的应用程序中使用 UINavigationController 及其栏 现在我想更改 leftBarButtonItem 和 rightBarButtonItem 的位置 我希望它们位于不同的 x 和 y 位置 具有自定义的宽度和高度
  • 如何选择Eclipse界面语言?

    我安装了 Flash Builder Burrito 版本并将其添加为dropin到我的日食 现在所有的 Eclipse 界面都是法语的 我真诚地热爱我的国家 但是D boguer and 世代相传真的没有那么性感Debug and 构建路
  • 查一下X509Certificate2是否被撤销?

    我怎样才能知道是否X509Certificate2已被撤销 我假设Verify 方法检查它 但它没有在帮助中明确说明 有人知道吗 另外 Verify 是否检查证书是否过期 您是否尝试过使用X509链条 http msdn microsoft
  • 如何找到 Phabricator 对象的 PHID?

    我需要在 Phabricator 安装中获取一个项目和多个用户的 PHID 看来找出如何做到这一点应该是微不足道的 但我搜索了文档却无济于事 我是不是找错地方了还是怎么的 最简单的方法 前往项目 单击新建任务 查看 URL 它会有一个参数
  • C++ 中的 const 运算符重载问题

    我在使用 const 版本重载 operator 时遇到问题 include
  • C函数判断IP地址是否为多播地址

    如果用户输入一些IP地址 例如 239 4 4 4 我如何使用linux C中可用的任何函数确定该IP地址是多播的 IPv4 多播地址由最高有效位定义1110 so 如果IP地址存储为32位unsigned变量 应用 gt gt 28到变量
  • 如何使用 vb.net 比较字符串的百分比匹配?

    我用头撞墙有一段时间了 现在正在尝试不同的技术 它们都工作得不好 我有两根弦 我需要比较它们并获得准确的匹配百分比 IE 四分和七年前 TO 对于分数和七年前 好吧 我首先将每个单词与每个单词进行比较 跟踪每个命中 然后百分比 count
  • .NET 4 ISet<> HashSet<> 可以替代 NHibernate Iesi.Collections ISet 、 HashSet 吗?

    NET 4 ISet HashSet 可以替换 NHibernate Iesi Collections ISet HashSet 吗 我正在使用 Castle 代理和 NHibernate 3 0 是的 有两种方法 将您的收藏声明为ICol
  • 是否可以使用变量动态更改代码中的类名称?

    我有这个功能 NSString getId id id field withColumn int test column withTable NSString tableName renvoyer le label NSError erro
  • 为什么结构化绑定禁用 RVO 并移动 return 语句?

    假设我们有一个名为AAA支持两者复制 移动 class AAA public AAA default AAA default AAA const AAA rhs std cout lt lt Copy constructor lt lt s