【问题标题】:If rvalues did not bind to const references, how would this affect move semantics and perfect forwarding?如果右值没有绑定到 const 引用,这将如何影响移动语义和完美转发?
【发布时间】:2013-11-04 05:20:38
【问题描述】:

http://www.reddit.com/r/IAmA/comments/1nl9at/i_am_a_member_of_facebooks_hhvm_team_a_c_and_d/ccjm2qs,Andrei Alexandrescu 写道:

我认为将右值绑定到 const 引用是一个小错误 这导致了右值引用兴登堡......这将是一个很长的 讨论。首次引入时将右值绑定到 const& 是有意义的 (没有模板,很少有细微之处)但从长远来看,它实际上是 无法区分被调用方的右值和左值。 这反过来又迫使一个过于复杂的解决方案(右值引用)作为 一个昂贵的修复。

如果没有选择将右值绑定到 const 引用,这将如何影响移动语义和完美转发?

【问题讨论】:

  • 这是 Andrei Alexandrescu 的观点。那么我们如何支持他的主张呢?如果是一般的社区意见,那么我们可能会支持,但它是个人的意见,在很多事情上经常有不同的意见,比如迭代器,被 C++ 专家很好地接受。
  • 我们不需要在被调用方进行区分。它作为常量引用传递并且应该只是readable,而不是writable。并且右值引用不是overly complex
  • 我已经改写了这个问题,使其符合事实而非基于意见。
  • 如果右值不绑定到 const 引用,它们绑定到什么?没有?非const 引用?仅实例?

标签: c++ c++11


【解决方案1】:

我不打算触及这个问题,因为它是一个非常假设的问题,没有太大的回答价值。但我改变了主意。回答这个我以前不理解的问题有价值。

考虑使用通用 API(不是在 C++ 中,而是在一般计算机语言中)基于一个或多个分隔符将字符串拆分为字符串数组。理想情况下,这会将“字符串视图”或“字符串引用”返回到原始字符串中,以避免复制原始字符串的片段。 “字符串视图”或“string_ref”只不过是原始字符串的一对迭代器。所以像:

vector<string_ref> split(const string& str, const string& delim);

既然知道vector&lt;string_ref&gt; 引用回str,那么将此函数绑定到右值是个坏主意。一旦客户开始使用结果,对参数的引用就会消失。引用将悬空。

因此,最好禁止此函数接受 str 的右值参数,即使它不会修改此参数。

话虽如此,我们有数十年的经验强烈表明这个例子不是典型的。大多数情况下,如果函数不打算修改参数,那么该参数是右值还是左值都没有关系。

因此,如果我们有一张干净的表格,那么让普通情况成为最容易处理的情况是有意义的:右值可以绑定到const X&amp;。但是对于像split 这样的情况,我们需要语法来禁止这种常见的默认行为。怎么样:

vector<string_ref> split(const string& str, const string& delim);
vector<string_ref> split(const string&& str, const string& delim) = delete;

我很难想出比这更优雅的东西。

换句话说:通常情况下,由于 20/20 事后诸葛亮,并且缺乏向后兼容性限制,重新设计可以做得更好,给定一张干净的床单。但在这种情况下,我假设自己是一张干净的床单,我很难想出比我们现有的更好的设计。

&lt;Disclaimer&gt; 我有偏见。 &lt;/Disclaimer&gt;

【讨论】:

  • 我从事的一个项目恰好遇到了这个问题。我们基本上决定记录行为并让用户负责确保可查看对象不是临时的(或超出范围)。当然不是很好。
  • @KonradRudolph:您能否使用重载的已删除函数来执行您的策略,如本答案所示? (假设你的编译器实现了 C++11)。
  • 那是在 C++11 之前。 deleted 函数当然可以工作,但只会阻止使用临时对象,而不是视图超过其宿主对象的其他情况。
  • @KonradRudolph:我猜无论临时(右值)是否绑定到 const 左值引用(OP 问题的前提),其他情况都不会被阻止。
  • @Howard,你还记得这个更简单的方案是什么吗? informit.com/articles/article.aspx?p=1622265 "我非常严格地遵循了 C++ 的右值提议,并且有一次我提出了一个更简单的方案,Howard Hinnant 向我证明会破坏兼容性(这是一个禁忌)。"
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-09-04
  • 1970-01-01
  • 2017-04-13
  • 1970-01-01
  • 1970-01-01
  • 2013-02-14
  • 2010-11-21
相关资源
最近更新 更多