为什么std :: move of std :: shared_ptr会被销毁

问题描述 投票:0回答:2

我有一些类似的代码

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

的情况类似
c++ reference move shared-ptr
2个回答
0
投票

由于使用std::move,您已将返回值转换为参考值。而不是const引用,因此是临时的。

所以没有复制发生,并且行结束时,返回值被破坏。


0
投票

您正在比较两种不同的事物。

p && j = f(2)

这将使用对f(2)返回的对象的引用来初始化引用,并且这将延长f(2)返回的值的寿命,因此可以。

p && k = move(f(3));

此操作将使用对move返回的对象的引用来初始化引用,这将延长move返回的值的寿命(这是对f(2)返回的临时对象的引用),但返回的临时对象f(2)死了,因为它的生存期没有延长(没有分配给参考变量),所以k最终成为了悬空的参考。

© www.soinside.com 2019 - 2024. All rights reserved.