在回复question about returning temporaries 之后,我发现还有第二个回复,该回复略有不同。
它不是通过值返回,而是通过右值引用返回。 您能否解释一下这些方法之间的区别以及它们的风险所在?
struct Bar
{
Bar& doThings() & {return *this;}
// Returning rvalue reference
Bar&& doThings() && {return std::move(*this);}
// Alternative: Returning by value
//Bar doThings() && {return std::move(*this);}
std::unique_ptr<int> m_content; // A non-copyable type
};
答案 0 :(得分:3)
主要区别在于,如果返回右值引用,则当将返回值绑定到引用时,临时对象的生存期将不会延长。
例如,
{{1}}
答案 1 :(得分:0)
我对此感兴趣,所以我打开了一个小测试程序:
#include <memory>
#include <iostream>
struct Bar
{
// Return by reference
Bar& doThings() & { return *this; }
// Return by rvalue reference
Bar&& doThings() && { std::cout << "in Bar&& doThings, this=" << (void *) this << "\n"; return std::move (*this); }
~Bar () { std::cout << "Bar destroyed at " << (void *) this << "\n"; }
int first;
std::unique_ptr<int> m_content; // Make Bar a non-copyable type
};
int main ()
{
std::cout << std::hex;
Bar bar;
std::cout << "bar is at " << &bar << "\n";
Bar& bar_ref = bar.doThings ();
std::cout << "bar_ref refers to " << &bar_ref.first << "\n\n";
Bar&& bar_rvalue_ref = Bar ().doThings ();
std::cout << "bar_rvalue_ref refers to " << &bar_rvalue_ref.first << "\n\n";
}
输出:
bar is at 0x7ffdc10846f0
bar_ref refers to 0x7ffdc10846f0
in Bar&& doThings, this=0x7ffdc1084700
Bar destroyed at 0x7ffdc1084700
bar_rvalue_ref refers to 0x7ffdc1084700
Bar destroyed at 0x7ffdc10846f0
因此,这告诉我们doThings()
的任何形式都不创建临时文件。您也可以在Godbolt上进行验证。
那么,看看书面的Bar
的实现,这会给我们什么?好吧,我个人在Bar&& doThings()
中根本看不到任何目的,因为:
*this
中移动出来的,因此它在原则上吞噬了新构造的对象,因此不应依赖返回的引用(仍然引用该对象)。 Bar& doThings()
可以正常工作(并且实际上返回指向对象本身的指针,因此不会涉及任何复制或临时操作)。
我确定我错过了一些重要的事情,所以我很想听听人们对此的反应。当然,也许在更复杂的情况下,通过右值引用返回 some 的目的。谢谢。