为什么C++委员会决定const引用应该延长temporaries的生命周期?
这个事实已经在网上广泛讨论过,包括stackoverflow.解释这种情况的最终资源可能就是GoTW:
这种语言功能的基本原理是什么?它知道了吗?
(另一种选择是临时的寿命不会被任何参考文献扩展.)
我自己的宠物理论的基本原理是这种行为允许对象隐藏实现细节.使用此规则,成员函数可以在不对客户端代码进行任何更改的情况下,在返回值或const引用与已内部存在的值之间切换.例如,矩阵类可能能够返回行向量和列向量.为了最小化副本,可以返回一个或另一个作为参考,具体取决于实现(行主要与列主要).无论通过引用返回哪一个都必须通过复制并返回该值来返回(如果返回的向量是连续的).库编写者可能希望在未来改变实现(行主要与列专业),并防止客户端编写强烈依赖于实现是行主要还是列主要的代码.通过要求客户端接受返回值为const ref,矩阵类可以返回const引用或值,而无需对客户端代码进行任何更改.无论如何,如果原始的理由是已知的,我想知道它.
所以我有以下功能:
void scan(std::istream& is, Handler& h);
Run Code Online (Sandbox Code Playgroud)
我想以不同的方式称呼它,例如:
scan(std::cin, Handler());
scan(std::ifstream("myfile"), myhandler);
Run Code Online (Sandbox Code Playgroud)
编译器抱怨std::ifstream("myfile")并且Handler()将rvalues作为非const引用传递,因此投诉是合法的,但我该怎么办?
const(istream读取时修改,处理程序在回调期间更改其状态).&&),那么我将无法通过std::cin,有时我真的关心最终状态,myhandler因此我也无法应用std::move它们.auto&&类型推导使参数成为通用引用,从而为lvalue和rvalue引用的所有可能组合重载此函数,但我不打算将此函数重载为我已经指定的其他类型.还有其他选择吗?
不知何故,整个移动语义在这样一个微不足道的例子中受到了阻碍.
以下内容无法编译:
#include <iostream>
using namespace std;
int x = 5;
int && f () { return std::move(x); }
int g(int & y) { return y; }
int main() {
g(f());
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我很清楚为什么prvalues(未命名的临时值)不会绑定到非const值左右 - 它们修改它们没有意义,因为它们很快就会消失.然而为什么xvalues不绑定到非const左值引用?
如果一个函数返回int &&,引用的对象不能是临时的,否则我们会得到一个悬空引用.因此,如果a int &&返回,那么,根据我的理解,这是一个参考,并附加保证可以安全地从中移动.
编辑:措辞更正:"值"绑定到"引用",反之则不然.
第二次编辑:以下编译 - 我没有看到概念上的差异,除了现在是左值.但它仍然引用x.我理解为什么这应该编译,而上面不应该通过语言规范.但是,我不理解它背后的原因.为什么仅仅混叠会改变图片?
#include <iostream>
using namespace std;
int x = 5;
int && f () { return std::move(x); }
int g(int & y) { return y; }
int main() {
int && y = f(); …Run Code Online (Sandbox Code Playgroud)