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

Jon*_*Jon 5 c++ c++11

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

我认为将rvalues绑定到const引用是导致rvalue引用兴登堡的一个小错误......这将是一个长期的讨论.将rvalues绑定到const并在首次引入时有意义(没有模板,很少有细微之处),但从长远来看,几乎不可能区分rvalues和被叫方左边的左值.这反过来迫使一个过于复杂的解决方案(右值引用)作为昂贵的解决方案.

如果没有选择将rvalues绑定到const引用,那么它将如何影响移动语义和完美转发?

How*_*ant 6

我不打算触及这个问题,认为这是一个非常假设的问题,在回答时没什么价值.但我改变了主意.还有就是在回答这个问题之前,我以前没有理解价值.

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

vector<string_ref> split(const string& str, const string& delim);
Run Code Online (Sandbox Code Playgroud)

如果已知vector<string_ref>引用str,则将此函数绑定到右值是一个坏主意.一旦客户端开始使用结果,对参数的引用就会消失.引用将是悬空.

因此,禁止此函数接受rvalue参数是一个好主意str,即使它不会修改此参数.

话虽如此,我们有数十年的经验,强烈表明这个例子并不典型.大多数情况下,如果函数不会修改参数,那么该参数是否是rvalue或lvalue并不重要.

因此,如果我们有一个干净的表格,那么使常见案例最容易处理是有意义的:rvalues可以绑定const X&.但是对于类似的情况split,我们需要语法来禁止这种常见的默认行为.怎么样:

vector<string_ref> split(const string& str, const string& delim);
vector<string_ref> split(const string&& str, const string& delim) = delete;
Run Code Online (Sandbox Code Playgroud)

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

换句话说:通常,凭借20/20后见之明以及缺乏向后兼容性限制,在重新设计的情况下,给定一张干净的纸张可以做得更好.但在这种情况下,我假设自己是一张干净的床单,而且我遇到了比我们更好的设计.

<Disclaimer> 我很有偏见. </Disclaimer>