传递unique_ptr右值引用结果编译错误

时间:2017-10-17 06:18:10

标签: c++ c++11

以下是示例代码:

using namespace std;
struct A {
    A(unique_ptr<int> s)
    : _s(move(s)){}

    unique_ptr<int> _s;
};

int main(int argc, const char * argv[]) {

    auto&& ptr = make_unique<int>(5);
    A a{ptr}; // Error
    A b{move(ptr)}; // OK 
    return 0;
}

我的第一个猜测是,它应该可以在不使用&#39; move&#39;的情况下工作,但我会调用隐式删除的复制构造函数&#39;在clang上。也许是&#39; ptr&#39;是不是左值(奇怪的是?)?有人可以澄清一下吗?

2 个答案:

答案 0 :(得分:5)

这里有几件事情,其中​​大部分涉及价值类别分类中各部分的标准的措辞。但这是它的要点:

ptr类型的扣除将遵循转发引用的规则。是的,它将是unique_ptr<int>&&。但ptr不是左值。这是理解的棘手问题。它是一个你已经绑定到rvalue的引用,当然,但现在该对象不再是未命名的,也不是对它的引用。

现在它是一个带名字的对象。直觉上,因为你可以分配它,它是一个左值(在一般意义上)。因此,它不会自己绑定到右值引用。所以你最终试图调用复制构造函数。

要移动它,您需要再次将其转换为过期值(从类型系统的角度来看)。这就是std::move通过返回一个(未命名的)右值引用来做的事情。

答案 1 :(得分:1)

传递一个r值:

A a{ make_unique<int>(5) };

或std ::移动l值

auto ptr = make_unique<int>(5);
A b{ move(ptr) };