我有一些类似的代码
struct A
{
int i;
A(int i) : i(i) {}
~A()
{
cout << "destroy " << i << endl;
}
};
using p = shared_ptr<A>;
p f(int i)
{
return make_shared<A>(i);
}
int main()
{
auto i = f(1);
cout << "a" << endl;
p && j = f(2);
cout << "a" << endl;
p && k = move(f(3));
cout << "a" << endl;
auto l = move(f(4));
cout << "a" << endl;
p ptr = make_shared<A>(5);
auto && a = move(ptr);
cout << "a" << endl;
}
输出为
a
a
destroy 3
a
a
a
destroy 5
destroy 4
destroy 2
destroy 1
我不明白为什么move
函数返回右值引用的返回值会导致破坏。但是直接将其放在右值引用中也可以。
实际上是在std::get<>
的std::tuple
中发现了问题。我有一个函数,返回两个shared_ptr的元组,并使用std :: get <>访问该元素。但是我发现auto && i = get<0>(f())
会导致错误,但auto i = get<0>(f())
不会。然后我发现std :: move
由于使用std::move
,您已将返回值转换为参考值。而不是const引用,因此是临时的。
所以没有复制发生,并且行结束时,返回值被破坏。
您正在比较两种不同的事物。
p && j = f(2)
这将使用对f(2)
返回的对象的引用来初始化引用,并且这将延长f(2)
返回的值的寿命,因此可以。
p && k = move(f(3));
此操作将使用对move
返回的对象的引用来初始化引用,这将延长move
返回的值的寿命(这是对f(2)
返回的临时对象的引用),但返回的临时对象f(2)
死了,因为它的生存期没有延长(没有分配给参考变量),所以k
最终成为了悬空的参考。