以下是我理解的摘要,希望有人可以纠正它:
物业:
T foo() { ... return expr; } main() { T var = foo(); }
我对回归过程的理解是否正确?
> expr的求值结果被隐式转换为声明的函数返回类型T.此转换发生在foo()中;
>上面的转换值用于初始化临时对象,比如“x”.子问题:第二次转换是在foo()还是main()中发生的?
>临时对象“x”用于初始化main()中的变量var.
欢迎任何输入!
解决方法
如果函数声明为T f();,并且T不是void,并且函数正常返回,则它必须通过返回e;形式的语句返回,其中e是某个表达式.
当您计算函数调用表达式f()时,您将获得一个值.假设U表示对象类型.如果T = U&或者T = U&&,然后该值是U型,表达式e必须能够绑定到引用,返回值是e的值. (就其价值类别而言,返回值也是所谓的“glvalue”).在这种情况下没有其他事情发生.函数调用的值是返回的东西.
然而,当T = U时,f()的值是所谓的“prvalue”(“纯rvalue”),这就需要构造U类型的临时对象.这个对象的构造就像通过U obj = e(即从e隐式转换).然后f()的值就是这个临时对象.它可以用于初始化另一个对象(例如U x = f();),或者它可以绑定到一个引用(例如U&& r = f();).
返回表达式e与函数调用值的绑定作为函数体范围内的最后一件事发生.值得注意的是,这是在范围结束之前,即在范围本地对象被销毁之前.例如,如果在构造返回值对象期间抛出异常,则在异常传递给调用范围之前,必须发生范围展开以销毁本地对象.另一个有用的例子可能是使用范围防护装置,例如:互斥锁:
U f() { std::locK_guard<std::mutex> lock(state_mutex); return state.get_value(); }
这里我们假设初始化U obj = state.get_value();是有道理的,我们进一步假设只有在state_mutex被锁定时才能调用state.get_value().上面的代码正确而简洁地完成了这一过程.