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

If rvalues did not bind to const references, how would this affect move semantics and perfect forwarding?

本文关键字:影响 何影响 移动 转发 完美 语义 绑定 引用 const 如果      更新时间:2023-10-16

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

我认为将右值绑定到常量引用是一个小错误导致右耳值参考兴登堡。。。这将是一个漫长的过程讨论将右值绑定到常量&第一次介绍时很有意义(没有模板,几乎没有微妙之处(,但从长远来看,它实际上无法区分被调用者端的右值和左值。这反过来又迫使一个过于复杂的解决方案(右值引用(昂贵的修复。

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

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

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

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

既然vector<string_ref>引用回str,那么这个函数绑定到右值是个坏主意。一旦客户开始使用结果,对参数的引用就会消失很久。这些参考资料将是悬空的。

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

也就是说,我们有几十年的经验,这有力地表明这个例子不是典型的。大多数时候,如果函数不打算修改参数,那么该参数是右值还是左值都无关紧要。

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

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

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

换言之:通常,有了20/20后见之明的好处,再加上缺乏向后兼容性约束,在没有失误的情况下,重新设计可以做得更好。但在这种情况下,我假设自己是清白的,我很难想出比我们现有的更好的设计。

<Disclaimer>我有偏见。</Disclaimer>