我对此很感兴趣,所以我敲了一个小测试程序:
#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验证这一点。
那么,看看 aswritten 的实现,Bar
这会给我们留下什么?好吧,我个人根本看不到任何目的,Bar&& doThings()
因为:
- AFAICT,您只能在新构造的对象上调用它,所以无论如何它似乎没什么意义。
- 因为它从移动
*this
,所以原则上它会吃掉那个新构造的对象,所以返回的引用(仍然引用它)是不可靠的。
- 正如@xskxzr 已经指出的那样,在步骤 1 中创建的临时对象的生命周期非常短。
然而,Bar& doThings()
工作得很好(实际上,返回一个指向对象本身的指针,因此不会涉及复制或临时对象)。
我确定我错过了一些重要的事情,所以我很想听听人们对此的反应。当然,通过右值引用返回是有一些目的的,也许在更复杂的情况下。谢谢。
现场演示